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