diff options
-rw-r--r-- | llvm/include/llvm/MC/MCInstrDesc.h | 8 | ||||
-rw-r--r-- | llvm/include/llvm/Target/Target.td | 1 | ||||
-rw-r--r-- | llvm/lib/MC/MCInstrDesc.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 26 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenInstruction.cpp | 1 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenInstruction.h | 1 | ||||
-rw-r--r-- | llvm/utils/TableGen/InstrDocsEmitter.cpp | 1 | ||||
-rw-r--r-- | llvm/utils/TableGen/InstrInfoEmitter.cpp | 1 |
11 files changed, 23 insertions, 39 deletions
diff --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h index ba97aeb837b..61e7d09afbc 100644 --- a/llvm/include/llvm/MC/MCInstrDesc.h +++ b/llvm/include/llvm/MC/MCInstrDesc.h @@ -151,7 +151,8 @@ enum Flag { InsertSubreg, Convergent, Add, - Trap + Trap, + VariadicOpsAreDefs, }; } @@ -383,6 +384,11 @@ public: /// additional values. bool isConvergent() const { return Flags & (1ULL << MCID::Convergent); } + /// Return true if variadic operands of this instruction are definitions. + bool variadicOpsAreDefs() const { + return Flags & (1ULL << MCID::VariadicOpsAreDefs); + } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index abb1bb431f6..e4b827babb9 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -479,6 +479,7 @@ class Instruction { bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg? // If so, make sure to override // TargetInstrInfo::getInsertSubregLikeInputs. + bit variadicOpsAreDefs = 0; // Are variadic operands definitions? // Does the instruction have side effects that are not captured by any // operands of the instruction or other flags? diff --git a/llvm/lib/MC/MCInstrDesc.cpp b/llvm/lib/MC/MCInstrDesc.cpp index ee55f3eff3a..53cba864a85 100644 --- a/llvm/lib/MC/MCInstrDesc.cpp +++ b/llvm/lib/MC/MCInstrDesc.cpp @@ -39,15 +39,6 @@ bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI, return false; if (hasDefOfPhysReg(MI, PC, RI)) return true; - // A variadic instruction may define PC in the variable operand list. - // There's currently no indication of which entries in a variable - // list are defs and which are uses. While that's the case, this function - // needs to assume they're defs in order to be conservatively correct. - for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) { - if (MI.getOperand(i).isReg() && - RI.isSubRegisterEq(PC, MI.getOperand(i).getReg())) - return true; - } return false; } @@ -66,5 +57,10 @@ bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg, if (MI.getOperand(i).isReg() && RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) return true; + if (variadicOpsAreDefs()) + for (int i = NumOperands - 1, e = MI.getNumOperands(); i != e; ++i) + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) + return true; return hasImplicitDefOfPhysReg(Reg, &RI); } diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 76f8414e8f0..ece722ec7ba 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -3334,7 +3334,7 @@ multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f, let hasSideEffects = 0 in { -let mayLoad = 1, hasExtraDefRegAllocReq = 1 in +let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index 3c153625b01..e2fa7b10f56 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -781,7 +781,7 @@ defm tSTRH : thumb_st_rr_ri_enc<0b001, 0b1000, t_addrmode_rr, // These require base address to be written back or one of the loaded regs. let hasSideEffects = 0 in { -let mayLoad = 1, hasExtraDefRegAllocReq = 1 in +let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops), IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> { bits<3> Rn; @@ -826,7 +826,8 @@ def : InstAlias<"ldm${p} $Rn!, $regs", (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs), 0>, Requires<[IsThumb, IsThumb1Only]>; -let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in +let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1, + variadicOpsAreDefs = 1 in def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops), IIC_iPop, "pop${p}\t$regs", []>, diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 0c5720e0267..183116b857a 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -1775,7 +1775,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin, let hasSideEffects = 0 in { -let mayLoad = 1, hasExtraDefRegAllocReq = 1 in +let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in defm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>; multiclass thumb2_st_mult<string asm, InstrItinClass itin, diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 203da11ed32..3832b0112b8 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -9177,33 +9177,9 @@ bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const { // Any arithmetic instruction which writes to the PC also terminates the IT // block. - for (unsigned OpIdx = 0; OpIdx < MCID.getNumDefs(); ++OpIdx) { - MCOperand &Op = Inst.getOperand(OpIdx); - if (Op.isReg() && Op.getReg() == ARM::PC) - return true; - } - - if (MCID.hasImplicitDefOfPhysReg(ARM::PC, MRI)) + if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI)) return true; - // Instructions with variable operand lists, which write to the variable - // operands. We only care about Thumb instructions here, as ARM instructions - // obviously can't be in an IT block. - switch (Inst.getOpcode()) { - case ARM::tLDMIA: - case ARM::t2LDMIA: - case ARM::t2LDMIA_UPD: - case ARM::t2LDMDB: - case ARM::t2LDMDB_UPD: - if (listContainsReg(Inst, 3, ARM::PC)) - return true; - break; - case ARM::tPOP: - if (listContainsReg(Inst, 2, ARM::PC)) - return true; - break; - } - return false; } diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp index 2a6749a6136..6d06ba2c8b6 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -370,6 +370,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) isConvergent = R->getValueAsBit("isConvergent"); hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo"); FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore"); + variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs"); bool Unset; mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset); diff --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h index 990ea21051b..2e3d2f48a92 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.h +++ b/llvm/utils/TableGen/CodeGenInstruction.h @@ -275,6 +275,7 @@ template <typename T> class ArrayRef; bool FastISelShouldIgnore : 1; bool hasChain : 1; bool hasChain_Inferred : 1; + bool variadicOpsAreDefs : 1; std::string DeprecatedReason; bool HasComplexDeprecationPredicate; diff --git a/llvm/utils/TableGen/InstrDocsEmitter.cpp b/llvm/utils/TableGen/InstrDocsEmitter.cpp index 41dc37a7ab3..9d50351854e 100644 --- a/llvm/utils/TableGen/InstrDocsEmitter.cpp +++ b/llvm/utils/TableGen/InstrDocsEmitter.cpp @@ -138,6 +138,7 @@ void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) { FLAG(isInsertSubreg) FLAG(isConvergent) FLAG(hasNoSchedulingInfo) + FLAG(variadicOpsAreDefs) if (!FlagStrings.empty()) { OS << "Flags: "; bool IsFirst = true; diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index 33711b64a5d..3bc07d96940 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -625,6 +625,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; + if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)"; // Emit all of the target-specific flags... BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); |