gccint: Side Effects
1
1 14.15 Side Effect Expressions
1 =============================
1
1 The expression codes described so far represent values, not actions.
1 But machine instructions never produce values; they are meaningful only
1 for their side effects on the state of the machine. Special expression
1 codes are used to represent side effects.
1
1 The body of an instruction is always one of these side effect codes;
1 the codes described above, which represent values, appear only as the
1 operands of these.
1
1 '(set LVAL X)'
1 Represents the action of storing the value of X into the place
1 represented by LVAL. LVAL must be an expression representing a
1 place that can be stored in: 'reg' (or 'subreg', 'strict_low_part'
1 or 'zero_extract'), 'mem', 'pc', 'parallel', or 'cc0'.
1
1 If LVAL is a 'reg', 'subreg' or 'mem', it has a machine mode; then
1 X must be valid for that mode.
1
1 If LVAL is a 'reg' whose machine mode is less than the full width
1 of the register, then it means that the part of the register
1 specified by the machine mode is given the specified value and the
1 rest of the register receives an undefined value. Likewise, if
1 LVAL is a 'subreg' whose machine mode is narrower than the mode of
1 the register, the rest of the register can be changed in an
1 undefined way.
1
1 If LVAL is a 'strict_low_part' of a subreg, then the part of the
1 register specified by the machine mode of the 'subreg' is given the
1 value X and the rest of the register is not changed.
1
1 If LVAL is a 'zero_extract', then the referenced part of the
1 bit-field (a memory or register reference) specified by the
1 'zero_extract' is given the value X and the rest of the bit-field
1 is not changed. Note that 'sign_extract' can not appear in LVAL.
1
1 If LVAL is '(cc0)', it has no machine mode, and X may be either a
1 'compare' expression or a value that may have any mode. The latter
1 case represents a "test" instruction. The expression '(set (cc0)
1 (reg:M N))' is equivalent to '(set (cc0) (compare (reg:M N)
1 (const_int 0)))'. Use the former expression to save space during
1 the compilation.
1
1 If LVAL is a 'parallel', it is used to represent the case of a
1 function returning a structure in multiple registers. Each element
1 of the 'parallel' is an 'expr_list' whose first operand is a 'reg'
1 and whose second operand is a 'const_int' representing the offset
1 (in bytes) into the structure at which the data in that register
1 corresponds. The first element may be null to indicate that the
1 structure is also passed partly in memory.
1
1 If LVAL is '(pc)', we have a jump instruction, and the
1 possibilities for X are very limited. It may be a 'label_ref'
1 expression (unconditional jump). It may be an 'if_then_else'
1 (conditional jump), in which case either the second or the third
1 operand must be '(pc)' (for the case which does not jump) and the
1 other of the two must be a 'label_ref' (for the case which does
1 jump). X may also be a 'mem' or '(plus:SI (pc) Y)', where Y may be
1 a 'reg' or a 'mem'; these unusual patterns are used to represent
1 jumps through branch tables.
1
1 If LVAL is neither '(cc0)' nor '(pc)', the mode of LVAL must not be
1 'VOIDmode' and the mode of X must be valid for the mode of LVAL.
1
1 LVAL is customarily accessed with the 'SET_DEST' macro and X with
1 the 'SET_SRC' macro.
1
1 '(return)'
1 As the sole expression in a pattern, represents a return from the
1 current function, on machines where this can be done with one
1 instruction, such as VAXen. On machines where a multi-instruction
1 "epilogue" must be executed in order to return from the function,
1 returning is done by jumping to a label which precedes the
1 epilogue, and the 'return' expression code is never used.
1
1 Inside an 'if_then_else' expression, represents the value to be
1 placed in 'pc' to return to the caller.
1
1 Note that an insn pattern of '(return)' is logically equivalent to
1 '(set (pc) (return))', but the latter form is never used.
1
1 '(simple_return)'
1 Like '(return)', but truly represents only a function return, while
1 '(return)' may represent an insn that also performs other functions
1 of the function epilogue. Like '(return)', this may also occur in
1 conditional jumps.
1
1 '(call FUNCTION NARGS)'
1 Represents a function call. FUNCTION is a 'mem' expression whose
1 address is the address of the function to be called. NARGS is an
1 expression which can be used for two purposes: on some machines it
1 represents the number of bytes of stack argument; on others, it
1 represents the number of argument registers.
1
1 Each machine has a standard machine mode which FUNCTION must have.
1 The machine description defines macro 'FUNCTION_MODE' to expand
1 into the requisite mode name. The purpose of this mode is to
1 specify what kind of addressing is allowed, on machines where the
1 allowed kinds of addressing depend on the machine mode being
1 addressed.
1
1 '(clobber X)'
1 Represents the storing or possible storing of an unpredictable,
1 undescribed value into X, which must be a 'reg', 'scratch',
1 'parallel' or 'mem' expression.
1
1 One place this is used is in string instructions that store
1 standard values into particular hard registers. It may not be
1 worth the trouble to describe the values that are stored, but it is
1 essential to inform the compiler that the registers will be
1 altered, lest it attempt to keep data in them across the string
1 instruction.
1
1 If X is '(mem:BLK (const_int 0))' or '(mem:BLK (scratch))', it
1 means that all memory locations must be presumed clobbered. If X
1 is a 'parallel', it has the same meaning as a 'parallel' in a 'set'
1 expression.
1
1 Note that the machine description classifies certain hard registers
1 as "call-clobbered". All function call instructions are assumed by
1 default to clobber these registers, so there is no need to use
1 'clobber' expressions to indicate this fact. Also, each function
1 call is assumed to have the potential to alter any memory location,
1 unless the function is declared 'const'.
1
1 If the last group of expressions in a 'parallel' are each a
1 'clobber' expression whose arguments are 'reg' or 'match_scratch'
1 (⇒RTL Template) expressions, the combiner phase can add the
1 appropriate 'clobber' expressions to an insn it has constructed
1 when doing so will cause a pattern to be matched.
1
1 This feature can be used, for example, on a machine that whose
1 multiply and add instructions don't use an MQ register but which
1 has an add-accumulate instruction that does clobber the MQ
1 register. Similarly, a combined instruction might require a
1 temporary register while the constituent instructions might not.
1
1 When a 'clobber' expression for a register appears inside a
1 'parallel' with other side effects, the register allocator
1 guarantees that the register is unoccupied both before and after
1 that insn if it is a hard register clobber. For pseudo-register
1 clobber, the register allocator and the reload pass do not assign
1 the same hard register to the clobber and the input operands if
1 Modifiers::) for the clobber and the hard register is in register
1 classes of the clobber in the alternative. You can clobber either
1 a specific hard register, a pseudo register, or a 'scratch'
1 expression; in the latter two cases, GCC will allocate a hard
1 register that is available there for use as a temporary.
1
1 For instructions that require a temporary register, you should use
1 'scratch' instead of a pseudo-register because this will allow the
1 combiner phase to add the 'clobber' when required. You do this by
1 coding ('clobber' ('match_scratch' ...)). If you do clobber a
1 pseudo register, use one which appears nowhere else--generate a new
1 one each time. Otherwise, you may confuse CSE.
1
1 There is one other known use for clobbering a pseudo register in a
1 'parallel': when one of the input operands of the insn is also
1 clobbered by the insn. In this case, using the same pseudo
1 register in the clobber and elsewhere in the insn produces the
1 expected results.
1
1 '(use X)'
1 Represents the use of the value of X. It indicates that the value
1 in X at this point in the program is needed, even though it may not
1 be apparent why this is so. Therefore, the compiler will not
1 attempt to delete previous instructions whose only effect is to
1 store a value in X. X must be a 'reg' expression.
1
1 In some situations, it may be tempting to add a 'use' of a register
1 in a 'parallel' to describe a situation where the value of a
1 special register will modify the behavior of the instruction. A
1 hypothetical example might be a pattern for an addition that can
1 either wrap around or use saturating addition depending on the
1 value of a special control register:
1
1 (parallel [(set (reg:SI 2) (unspec:SI [(reg:SI 3)
1 (reg:SI 4)] 0))
1 (use (reg:SI 1))])
1
1
1 This will not work, several of the optimizers only look at
1 expressions locally; it is very likely that if you have multiple
1 insns with identical inputs to the 'unspec', they will be optimized
1 away even if register 1 changes in between.
1
1 This means that 'use' can _only_ be used to describe that the
1 register is live. You should think twice before adding 'use'
1 statements, more often you will want to use 'unspec' instead. The
1 'use' RTX is most commonly useful to describe that a fixed register
1 is implicitly used in an insn. It is also safe to use in patterns
1 where the compiler knows for other reasons that the result of the
1 whole pattern is variable, such as 'movmemM' or 'call' patterns.
1
1 During the reload phase, an insn that has a 'use' as pattern can
1 carry a reg_equal note. These 'use' insns will be deleted before
1 the reload phase exits.
1
1 During the delayed branch scheduling phase, X may be an insn. This
1 indicates that X previously was located at this place in the code
1 and its data dependencies need to be taken into account. These
1 'use' insns will be deleted before the delayed branch scheduling
1 phase exits.
1
1 '(parallel [X0 X1 ...])'
1 Represents several side effects performed in parallel. The square
1 brackets stand for a vector; the operand of 'parallel' is a vector
1 of expressions. X0, X1 and so on are individual side effect
1 expressions--expressions of code 'set', 'call', 'return',
1 'simple_return', 'clobber' or 'use'.
1
1 "In parallel" means that first all the values used in the
1 individual side-effects are computed, and second all the actual
1 side-effects are performed. For example,
1
1 (parallel [(set (reg:SI 1) (mem:SI (reg:SI 1)))
1 (set (mem:SI (reg:SI 1)) (reg:SI 1))])
1
1 says unambiguously that the values of hard register 1 and the
1 memory location addressed by it are interchanged. In both places
1 where '(reg:SI 1)' appears as a memory address it refers to the
1 value in register 1 _before_ the execution of the insn.
1
1 It follows that it is _incorrect_ to use 'parallel' and expect the
1 result of one 'set' to be available for the next one. For example,
1 people sometimes attempt to represent a jump-if-zero instruction
1 this way:
1
1 (parallel [(set (cc0) (reg:SI 34))
1 (set (pc) (if_then_else
1 (eq (cc0) (const_int 0))
1 (label_ref ...)
1 (pc)))])
1
1 But this is incorrect, because it says that the jump condition
1 depends on the condition code value _before_ this instruction, not
1 on the new value that is set by this instruction.
1
1 Peephole optimization, which takes place together with final
1 assembly code output, can produce insns whose patterns consist of a
1 'parallel' whose elements are the operands needed to output the
1 resulting assembler code--often 'reg', 'mem' or constant
1 expressions. This would not be well-formed RTL at any other stage
1 in compilation, but it is OK then because no further optimization
1 remains to be done. However, the definition of the macro
1 'NOTICE_UPDATE_CC', if any, must deal with such insns if you define
1 any peephole optimizations.
1
1 '(cond_exec [COND EXPR])'
1 Represents a conditionally executed expression. The EXPR is
1 executed only if the COND is nonzero. The COND expression must not
1 have side-effects, but the EXPR may very well have side-effects.
1
1 '(sequence [INSNS ...])'
1 Represents a sequence of insns. If a 'sequence' appears in the
1 chain of insns, then each of the INSNS that appears in the sequence
1 must be suitable for appearing in the chain of insns, i.e. must
1 satisfy the 'INSN_P' predicate.
1
1 After delay-slot scheduling is completed, an insn and all the insns
1 that reside in its delay slots are grouped together into a
1 'sequence'. The insn requiring the delay slot is the first insn in
1 the vector; subsequent insns are to be placed in the delay slot.
1
1 'INSN_ANNULLED_BRANCH_P' is set on an insn in a delay slot to
1 indicate that a branch insn should be used that will conditionally
1 annul the effect of the insns in the delay slots. In such a case,
1 'INSN_FROM_TARGET_P' indicates that the insn is from the target of
1 the branch and should be executed only if the branch is taken;
1 otherwise the insn should be executed only if the branch is not
1 taken. ⇒Delay Slots.
1
1 Some back ends also use 'sequence' objects for purposes other than
1 delay-slot groups. This is not supported in the common parts of
1 the compiler, which treat such sequences as delay-slot groups.
1
1 DWARF2 Call Frame Address (CFA) adjustments are sometimes also
1 expressed using 'sequence' objects as the value of a
1 'RTX_FRAME_RELATED_P' note. This only happens if the CFA
1 adjustments cannot be easily derived from the pattern of the
1 instruction to which the note is attached. In such cases, the
1 value of the note is used instead of best-guesing the semantics of
1 the instruction. The back end can attach notes containing a
1 'sequence' of 'set' patterns that express the effect of the parent
1 instruction.
1
1 These expression codes appear in place of a side effect, as the body of
1 an insn, though strictly speaking they do not always describe side
1 effects as such:
1
1 '(asm_input S)'
1 Represents literal assembler code as described by the string S.
1
1 '(unspec [OPERANDS ...] INDEX)'
1 '(unspec_volatile [OPERANDS ...] INDEX)'
1 Represents a machine-specific operation on OPERANDS. INDEX selects
1 between multiple machine-specific operations. 'unspec_volatile' is
1 used for volatile operations and operations that may trap; 'unspec'
1 is used for other operations.
1
1 These codes may appear inside a 'pattern' of an insn, inside a
1 'parallel', or inside an expression.
1
1 '(addr_vec:M [LR0 LR1 ...])'
1 Represents a table of jump addresses. The vector elements LR0,
1 etc., are 'label_ref' expressions. The mode M specifies how much
1 space is given to each address; normally M would be 'Pmode'.
1
1 '(addr_diff_vec:M BASE [LR0 LR1 ...] MIN MAX FLAGS)'
1 Represents a table of jump addresses expressed as offsets from
1 BASE. The vector elements LR0, etc., are 'label_ref' expressions
1 and so is BASE. The mode M specifies how much space is given to
1 each address-difference. MIN and MAX are set up by branch
1 shortening and hold a label with a minimum and a maximum address,
1 respectively. FLAGS indicates the relative position of BASE, MIN
1 and MAX to the containing insn and of MIN and MAX to BASE. See
1 rtl.def for details.
1
1 '(prefetch:M ADDR RW LOCALITY)'
1 Represents prefetch of memory at address ADDR. Operand RW is 1 if
1 the prefetch is for data to be written, 0 otherwise; targets that
1 do not support write prefetches should treat this as a normal
1 prefetch. Operand LOCALITY specifies the amount of temporal
1 locality; 0 if there is none or 1, 2, or 3 for increasing levels of
1 temporal locality; targets that do not support locality hints
1 should ignore this.
1
1 This insn is used to minimize cache-miss latency by moving data
1 into a cache before it is accessed. It should use only
1 non-faulting data prefetch instructions.
1