Technically we could copy them if we could set up a mapping from one
sequence number to another, across the set of insns to be duplicated.
This seems overly complicated and error-prone since interblock motion
- from sched-ebb could move one of the pair of insns to a different block. */
+ from sched-ebb could move one of the pair of insns to a different block.
+
+ Also cannot allow jsr insns to be duplicated. If they throw exceptions,
+ then they'll be in a different block from their ldgp. Which could lead
+ the bb reorder code to think that it would be ok to copy just the block
+ containing the call and branch to the block containing the ldgp. */
static bool
alpha_cannot_copy_insn_p (rtx insn)
{
- rtx pat;
-
if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
return false;
-
- if (GET_CODE (insn) != INSN)
- return false;
- if (asm_noperands (insn) >= 0)
- return false;
-
- pat = PATTERN (insn);
- if (GET_CODE (pat) != SET)
+ if (recog_memoized (insn) >= 0)
+ return get_attr_cannot_copy (insn);
+ else
return false;
- pat = SET_SRC (pat);
- if (GET_CODE (pat) == UNSPEC_VOLATILE)
- {
- if (XINT (pat, 1) == UNSPECV_LDGP1
- || XINT (pat, 1) == UNSPECV_PLDGP2)
- return true;
- }
- else if (GET_CODE (pat) == UNSPEC)
- {
- if (XINT (pat, 1) == UNSPEC_LDGP2)
- return true;
- }
-
- return false;
}
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
-fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+ icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
]
(const_string "no")))
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated. This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another. This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+ (const_string "false"))
\f
;; Include scheduling descriptions.
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
;; We output a nop after noreturn calls at the very end of the function to
;; ensure that the return address always remains in the caller's code range,
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2")
+ "ldah %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2")
+ "lda %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:")
+ "ldgp %0,0(%1)\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")