summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCInstrDesc.h8
-rw-r--r--llvm/include/llvm/Target/Target.td1
-rw-r--r--llvm/lib/MC/MCInstrDesc.cpp14
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td2
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb.td5
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td2
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp26
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.cpp1
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.h1
-rw-r--r--llvm/utils/TableGen/InstrDocsEmitter.cpp1
-rw-r--r--llvm/utils/TableGen/InstrInfoEmitter.cpp1
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");
OpenPOWER on IntegriCloud