diff options
| author | Oliver Stannard <oliver.stannard@arm.com> | 2018-12-03 10:32:42 +0000 |
|---|---|---|
| committer | Oliver Stannard <oliver.stannard@arm.com> | 2018-12-03 10:32:42 +0000 |
| commit | 4cf35b4ab0bd34f23a986a2dc6b2fafc953f434f (patch) | |
| tree | 989f30cf88875938637802bdabbfda3e5cce5e2d /llvm | |
| parent | c588110f1340d997fb18f4fbbc7d363dc150cd71 (diff) | |
| download | bcm5719-llvm-4cf35b4ab0bd34f23a986a2dc6b2fafc953f434f.tar.gz bcm5719-llvm-4cf35b4ab0bd34f23a986a2dc6b2fafc953f434f.zip | |
[ARM][MC] Move information about variadic register defs into tablegen
Currently, variadic operands on an MCInst are assumed to be uses,
because they come after the defs. However, this is not always the case,
for example the Arm/Thumb LDM instructions write to a variable number of
registers.
This adds a property of instruction definitions which can be used to
mark variadic operands as defs. This only affects MCInst, because
MachineInstruction already tracks use/def per operand in each instance
of the instruction, so can already represent this.
This property can then be checked in MCInstrDesc, allowing us to remove
some special cases in ARMAsmParser::isITBlockTerminator.
Differential revision: https://reviews.llvm.org/D54853
llvm-svn: 348114
Diffstat (limited to 'llvm')
| -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"); |

