Skip to content

Commit

Permalink
[ARM][MC] Move information about variadic register defs into tablegen
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ostannard committed Dec 3, 2018
1 parent c588110 commit 4cf35b4
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 39 deletions.
8 changes: 7 additions & 1 deletion llvm/include/llvm/MC/MCInstrDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ enum Flag {
InsertSubreg,
Convergent,
Add,
Trap
Trap,
VariadicOpsAreDefs,
};
}

Expand Down Expand Up @@ -383,6 +384,11 @@ class MCInstrDesc {
/// 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
//===--------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
14 changes: 5 additions & 9 deletions llvm/lib/MC/MCInstrDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
}
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;

Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/ARM/ARMInstrThumb.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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", []>,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/ARMInstrThumb2.td
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 1 addition & 25 deletions llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CodeGenInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CodeGenInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/InstrDocsEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/InstrInfoEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 4cf35b4

Please sign in to comment.