Skip to content

Commit 4cf35b4

Browse files
committed
[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
1 parent c588110 commit 4cf35b4

File tree

11 files changed

+23
-39
lines changed

11 files changed

+23
-39
lines changed

llvm/include/llvm/MC/MCInstrDesc.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ enum Flag {
151151
InsertSubreg,
152152
Convergent,
153153
Add,
154-
Trap
154+
Trap,
155+
VariadicOpsAreDefs,
155156
};
156157
}
157158

@@ -383,6 +384,11 @@ class MCInstrDesc {
383384
/// additional values.
384385
bool isConvergent() const { return Flags & (1ULL << MCID::Convergent); }
385386

387+
/// Return true if variadic operands of this instruction are definitions.
388+
bool variadicOpsAreDefs() const {
389+
return Flags & (1ULL << MCID::VariadicOpsAreDefs);
390+
}
391+
386392
//===--------------------------------------------------------------------===//
387393
// Side Effect Analysis
388394
//===--------------------------------------------------------------------===//

llvm/include/llvm/Target/Target.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ class Instruction {
479479
bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg?
480480
// If so, make sure to override
481481
// TargetInstrInfo::getInsertSubregLikeInputs.
482+
bit variadicOpsAreDefs = 0; // Are variadic operands definitions?
482483

483484
// Does the instruction have side effects that are not captured by any
484485
// operands of the instruction or other flags?

llvm/lib/MC/MCInstrDesc.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,6 @@ bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI,
3939
return false;
4040
if (hasDefOfPhysReg(MI, PC, RI))
4141
return true;
42-
// A variadic instruction may define PC in the variable operand list.
43-
// There's currently no indication of which entries in a variable
44-
// list are defs and which are uses. While that's the case, this function
45-
// needs to assume they're defs in order to be conservatively correct.
46-
for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
47-
if (MI.getOperand(i).isReg() &&
48-
RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
49-
return true;
50-
}
5142
return false;
5243
}
5344

@@ -66,5 +57,10 @@ bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
6657
if (MI.getOperand(i).isReg() &&
6758
RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
6859
return true;
60+
if (variadicOpsAreDefs())
61+
for (int i = NumOperands - 1, e = MI.getNumOperands(); i != e; ++i)
62+
if (MI.getOperand(i).isReg() &&
63+
RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
64+
return true;
6965
return hasImplicitDefOfPhysReg(Reg, &RI);
7066
}

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3334,7 +3334,7 @@ multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f,
33343334

33353335
let hasSideEffects = 0 in {
33363336

3337-
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
3337+
let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
33383338
defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
33393339
IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">;
33403340

llvm/lib/Target/ARM/ARMInstrThumb.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ defm tSTRH : thumb_st_rr_ri_enc<0b001, 0b1000, t_addrmode_rr,
781781
// These require base address to be written back or one of the loaded regs.
782782
let hasSideEffects = 0 in {
783783

784-
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
784+
let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
785785
def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
786786
IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
787787
bits<3> Rn;
@@ -826,7 +826,8 @@ def : InstAlias<"ldm${p} $Rn!, $regs",
826826
(tLDMIA tGPR:$Rn, pred:$p, reglist:$regs), 0>,
827827
Requires<[IsThumb, IsThumb1Only]>;
828828

829-
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
829+
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1,
830+
variadicOpsAreDefs = 1 in
830831
def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
831832
IIC_iPop,
832833
"pop${p}\t$regs", []>,

llvm/lib/Target/ARM/ARMInstrThumb2.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
17751775

17761776
let hasSideEffects = 0 in {
17771777

1778-
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1778+
let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
17791779
defm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
17801780

17811781
multiclass thumb2_st_mult<string asm, InstrItinClass itin,

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9177,33 +9177,9 @@ bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
91779177

91789178
// Any arithmetic instruction which writes to the PC also terminates the IT
91799179
// block.
9180-
for (unsigned OpIdx = 0; OpIdx < MCID.getNumDefs(); ++OpIdx) {
9181-
MCOperand &Op = Inst.getOperand(OpIdx);
9182-
if (Op.isReg() && Op.getReg() == ARM::PC)
9183-
return true;
9184-
}
9185-
9186-
if (MCID.hasImplicitDefOfPhysReg(ARM::PC, MRI))
9180+
if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
91879181
return true;
91889182

9189-
// Instructions with variable operand lists, which write to the variable
9190-
// operands. We only care about Thumb instructions here, as ARM instructions
9191-
// obviously can't be in an IT block.
9192-
switch (Inst.getOpcode()) {
9193-
case ARM::tLDMIA:
9194-
case ARM::t2LDMIA:
9195-
case ARM::t2LDMIA_UPD:
9196-
case ARM::t2LDMDB:
9197-
case ARM::t2LDMDB_UPD:
9198-
if (listContainsReg(Inst, 3, ARM::PC))
9199-
return true;
9200-
break;
9201-
case ARM::tPOP:
9202-
if (listContainsReg(Inst, 2, ARM::PC))
9203-
return true;
9204-
break;
9205-
}
9206-
92079183
return false;
92089184
}
92099185

llvm/utils/TableGen/CodeGenInstruction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
370370
isConvergent = R->getValueAsBit("isConvergent");
371371
hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
372372
FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
373+
variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs");
373374

374375
bool Unset;
375376
mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);

llvm/utils/TableGen/CodeGenInstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ template <typename T> class ArrayRef;
275275
bool FastISelShouldIgnore : 1;
276276
bool hasChain : 1;
277277
bool hasChain_Inferred : 1;
278+
bool variadicOpsAreDefs : 1;
278279

279280
std::string DeprecatedReason;
280281
bool HasComplexDeprecationPredicate;

llvm/utils/TableGen/InstrDocsEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) {
138138
FLAG(isInsertSubreg)
139139
FLAG(isConvergent)
140140
FLAG(hasNoSchedulingInfo)
141+
FLAG(variadicOpsAreDefs)
141142
if (!FlagStrings.empty()) {
142143
OS << "Flags: ";
143144
bool IsFirst = true;

llvm/utils/TableGen/InstrInfoEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
625625
if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)";
626626
if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)";
627627
if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)";
628+
if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
628629

629630
// Emit all of the target-specific flags...
630631
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");

0 commit comments

Comments
 (0)