llvm.org GIT mirror llvm / 9639b46
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348114 91177308-0d34-0410-b5e6-96231b3b80d8 Oliver Stannard 1 year, 8 months ago
11 changed file(s) with 24 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
150150 InsertSubreg,
151151 Convergent,
152152 Add,
153 Trap
153 Trap,
154 VariadicOpsAreDefs,
154155 };
155156 }
156157
382383 /// additional values.
383384 bool isConvergent() const { return Flags & (1ULL << MCID::Convergent); }
384385
386 /// Return true if variadic operands of this instruction are definitions.
387 bool variadicOpsAreDefs() const {
388 return Flags & (1ULL << MCID::VariadicOpsAreDefs);
389 }
390
385391 //===--------------------------------------------------------------------===//
386392 // Side Effect Analysis
387393 //===--------------------------------------------------------------------===//
478478 bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg?
479479 // If so, make sure to override
480480 // TargetInstrInfo::getInsertSubregLikeInputs.
481 bit variadicOpsAreDefs = 0; // Are variadic operands definitions?
481482
482483 // Does the instruction have side effects that are not captured by any
483484 // operands of the instruction or other flags?
3838 return false;
3939 if (hasDefOfPhysReg(MI, PC, RI))
4040 return true;
41 // A variadic instruction may define PC in the variable operand list.
42 // There's currently no indication of which entries in a variable
43 // list are defs and which are uses. While that's the case, this function
44 // needs to assume they're defs in order to be conservatively correct.
45 for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
46 if (MI.getOperand(i).isReg() &&
47 RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
48 return true;
49 }
5041 return false;
5142 }
5243
6556 if (MI.getOperand(i).isReg() &&
6657 RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
6758 return true;
59 if (variadicOpsAreDefs())
60 for (int i = NumOperands - 1, e = MI.getNumOperands(); i != e; ++i)
61 if (MI.getOperand(i).isReg() &&
62 RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
63 return true;
6864 return hasImplicitDefOfPhysReg(Reg, &RI);
6965 }
33333333
33343334 let hasSideEffects = 0 in {
33353335
3336 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
3336 let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
33373337 defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
33383338 IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">;
33393339
780780 // These require base address to be written back or one of the loaded regs.
781781 let hasSideEffects = 0 in {
782782
783 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
783 let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
784784 def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
785785 IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
786786 bits<3> Rn;
825825 (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs), 0>,
826826 Requires<[IsThumb, IsThumb1Only]>;
827827
828 let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
828 let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1,
829 variadicOpsAreDefs = 1 in
829830 def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
830831 IIC_iPop,
831832 "pop${p}\t$regs", []>,
17741774
17751775 let hasSideEffects = 0 in {
17761776
1777 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1777 let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
17781778 defm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
17791779
17801780 multiclass thumb2_st_mult
91769176
91779177 // Any arithmetic instruction which writes to the PC also terminates the IT
91789178 // block.
9179 for (unsigned OpIdx = 0; OpIdx < MCID.getNumDefs(); ++OpIdx) {
9180 MCOperand &Op = Inst.getOperand(OpIdx);
9181 if (Op.isReg() && Op.getReg() == ARM::PC)
9182 return true;
9183 }
9184
9185 if (MCID.hasImplicitDefOfPhysReg(ARM::PC, MRI))
9186 return true;
9187
9188 // Instructions with variable operand lists, which write to the variable
9189 // operands. We only care about Thumb instructions here, as ARM instructions
9190 // obviously can't be in an IT block.
9191 switch (Inst.getOpcode()) {
9192 case ARM::tLDMIA:
9193 case ARM::t2LDMIA:
9194 case ARM::t2LDMIA_UPD:
9195 case ARM::t2LDMDB:
9196 case ARM::t2LDMDB_UPD:
9197 if (listContainsReg(Inst, 3, ARM::PC))
9198 return true;
9199 break;
9200 case ARM::tPOP:
9201 if (listContainsReg(Inst, 2, ARM::PC))
9202 return true;
9203 break;
9204 }
9179 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
9180 return true;
92059181
92069182 return false;
92079183 }
369369 isConvergent = R->getValueAsBit("isConvergent");
370370 hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
371371 FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
372 variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs");
372373
373374 bool Unset;
374375 mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
274274 bool FastISelShouldIgnore : 1;
275275 bool hasChain : 1;
276276 bool hasChain_Inferred : 1;
277 bool variadicOpsAreDefs : 1;
277278
278279 std::string DeprecatedReason;
279280 bool HasComplexDeprecationPredicate;
137137 FLAG(isInsertSubreg)
138138 FLAG(isConvergent)
139139 FLAG(hasNoSchedulingInfo)
140 FLAG(variadicOpsAreDefs)
140141 if (!FlagStrings.empty()) {
141142 OS << "Flags: ";
142143 bool IsFirst = true;
624624 if (Inst.isExtractSubreg) OS << "|(1ULL<
625625 if (Inst.isInsertSubreg) OS << "|(1ULL<
626626 if (Inst.isConvergent) OS << "|(1ULL<
627 if (Inst.variadicOpsAreDefs) OS << "|(1ULL<
627628
628629 // Emit all of the target-specific flags...
629630 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");