[llvm] r269352 - [ARM] Delay ARM constant pool creation. NFC.
Renato Golin via llvm-commits
llvm-commits at lists.llvm.org
Thu May 12 14:22:32 PDT 2016
Author: rengolin
Date: Thu May 12 16:22:31 2016
New Revision: 269352
URL: http://llvm.org/viewvc/llvm-project?rev=269352&view=rev
Log:
[ARM] Delay ARM constant pool creation. NFC.
This change adds a new constant pool kind to ARMOperand. When parsing the
operand for =immediate we create an instance of this operand rather than
creating a constant pool entry and rewriting the operand.
As the new operand kind is only created for ldr rt,= we can make ldr rt,=
an explicit pseudo instruction in ARM, Thumb and Thumb2
The pseudo instruction is expanded in processInstruction(). This creates the
constant pool and transforms the pseudo instruction into a pc-relative ldr to
the constant pool.
There are no functional changes and no modifications needed to existing tests.
Required by the patch that fixes PR25722.
Patch by Peter Smith.
Modified:
llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=269352&r1=269351&r2=269352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu May 12 16:22:31 2016
@@ -246,6 +246,15 @@ def shr_imm64 : Operand<i32>, ImmLeaf<i3
let ParserMatchClass = shr_imm64_asm_operand;
}
+
+// ARM Assembler operand for ldr Rd, =expression which generates an offset
+// to a constant pool entry or a MOV depending on the value of expression
+def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; }
+def const_pool_asm_imm : Operand<i32> {
+ let ParserMatchClass = const_pool_asm_operand;
+}
+
+
//===----------------------------------------------------------------------===//
// ARM Assembler alias templates.
//
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=269352&r1=269351&r2=269352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu May 12 16:22:31 2016
@@ -2792,6 +2792,12 @@ def LDRBT_POST
: ARMAsmPseudo<"ldrbt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q),
(outs GPR:$Rt)>;
+// Pseudo instruction ldr Rt, =immediate
+def LDRConstPool
+ : ARMAsmPseudo<"ldr${q} $Rt, $immediate",
+ (ins const_pool_asm_imm:$immediate, pred:$q),
+ (outs GPR:$Rt)>;
+
// Store
// Stores with truncate
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=269352&r1=269351&r2=269352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Thu May 12 16:22:31 2016
@@ -1543,3 +1543,8 @@ def : tInstAlias<"lsr${s}${p} $Rdm, $imm
(tLSRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
def : tInstAlias<"asr${s}${p} $Rdm, $imm",
(tASRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
+
+// Pseudo instruction ldr Rt, =immediate
+def tLDRConstPool
+ : tAsmPseudo<"ldr${p} $Rt, $immediate",
+ (ins tGPR:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=269352&r1=269351&r2=269352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu May 12 16:22:31 2016
@@ -4802,6 +4802,11 @@ def : t2InstAlias<"ldrsh${p}.w $Rt, $add
def : t2InstAlias<"add${p} $Rd, pc, $imm",
(t2ADR rGPR:$Rd, imm0_4095:$imm, pred:$p)>;
+// Pseudo instruction ldr Rt, =immediate
+def t2LDRConstPool
+ : t2AsmPseudo<"ldr${p} $Rt, $immediate",
+ (ins GPRnopc:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
+
// PLD/PLDW/PLI with alternate literal form.
def : t2InstAlias<"pld${p} $addr",
(t2PLDpci t2ldr_pcrel_imm12:$addr, pred:$p)>;
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=269352&r1=269351&r2=269352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu May 12 16:22:31 2016
@@ -427,8 +427,9 @@ class ARMOperand : public MCParsedAsmOpe
k_ShifterImmediate,
k_RotateImmediate,
k_ModifiedImmediate,
+ k_ConstantPoolImmediate,
k_BitfieldDescriptor,
- k_Token
+ k_Token,
} Kind;
SMLoc StartLoc, EndLoc, AlignmentLoc;
@@ -621,6 +622,11 @@ public:
return Imm.Val;
}
+ const MCExpr *getConstantPoolImm() const {
+ assert(isConstantPoolImm() && "Invalid access!");
+ return Imm.Val;
+ }
+
unsigned getVectorIndex() const {
assert(Kind == k_VectorIndex && "Invalid access!");
return VectorIndex.Val;
@@ -658,7 +664,9 @@ public:
bool isCCOut() const { return Kind == k_CCOut; }
bool isITMask() const { return Kind == k_ITCondMask; }
bool isITCondCode() const { return Kind == k_CondCode; }
- bool isImm() const override { return Kind == k_Immediate; }
+ bool isImm() const override {
+ return Kind == k_Immediate;
+ }
// checks whether this operand is an unsigned offset which fits is a field
// of specified width and scaled by a specific number of bits
template<unsigned width, unsigned scale>
@@ -1046,6 +1054,7 @@ public:
return ARM_AM::getSOImmVal(Value) == -1 &&
ARM_AM::getSOImmVal(-Value) != -1;
}
+ bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
bool isPostIdxReg() const {
@@ -1343,6 +1352,7 @@ public:
// If we have an immediate that's not a constant, treat it as a label
// reference needing a fixup. If it is a constant, it's something else
// and we reject it.
+
if (isImm() && !isa<MCConstantExpr>(getImm()))
return true;
@@ -1353,6 +1363,11 @@ public:
int64_t Val = Memory.OffsetImm->getValue();
return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
}
+ bool isConstPoolAsmImm() const {
+ // Delay processing of Constant Pool Immediate, this will turn into
+ // a constant. Match no other operand
+ return (isConstantPoolImm());
+ }
bool isPostIdxImm8() const {
if (!isImm()) return false;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
@@ -1965,6 +1980,7 @@ public:
}
const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
+
assert(SR && "Unknown value type!");
Inst.addOperand(MCOperand::createExpr(SR));
return;
@@ -2260,6 +2276,14 @@ public:
Inst.addOperand(MCOperand::createImm(Val));
}
+ void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ // This is container for the immediate that we will create the constant
+ // pool from
+ addExpr(Inst, getConstantPoolImm());
+ return;
+ }
+
void addMemTBBOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
@@ -2640,6 +2664,15 @@ public:
}
static std::unique_ptr<ARMOperand>
+ CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) {
+ auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate);
+ Op->Imm.Val = Val;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+ }
+
+ static std::unique_ptr<ARMOperand>
CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
Op->Bitfield.LSB = LSB;
@@ -2896,6 +2929,9 @@ void ARMOperand::print(raw_ostream &OS)
OS << "<mod_imm #" << ModImm.Bits << ", #"
<< ModImm.Rot << ")>";
break;
+ case k_ConstantPoolImmediate:
+ OS << "<constant_pool_imm #" << *getConstantPoolImm();
+ break;
case k_BitfieldDescriptor:
OS << "<bitfield " << "lsb: " << Bitfield.LSB
<< ", width: " << Bitfield.Width << ">";
@@ -5217,10 +5253,7 @@ bool ARMAsmParser::parseOperand(OperandV
if (getParser().parseExpression(SubExprVal))
return true;
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
-
- const MCExpr *CPLoc =
- getTargetStreamer().addConstantPoolEntry(SubExprVal, S);
- Operands.push_back(ARMOperand::CreateImm(CPLoc, S, E));
+ Operands.push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E));
return false;
}
}
@@ -6835,6 +6868,34 @@ bool ARMAsmParser::processInstruction(MC
case ARM::t2LDRSHpcrel:
Inst.setOpcode(ARM::t2LDRSHpci);
return true;
+ case ARM::LDRConstPool:
+ case ARM::tLDRConstPool:
+ case ARM::t2LDRConstPool: {
+ // Handle the pseudo instruction for ldr rn,=
+ // For now we always create the constant pool entry and load from it
+ // FIXME: Use a MOV or MVN when the immediate will fit
+ MCInst TmpInst;
+ if (Inst.getOpcode() == ARM::LDRConstPool)
+ TmpInst.setOpcode(ARM::LDRi12);
+ else if (Inst.getOpcode() == ARM::tLDRConstPool)
+ TmpInst.setOpcode(ARM::tLDRpci);
+ else if (Inst.getOpcode() == ARM::t2LDRConstPool)
+ TmpInst.setOpcode(ARM::t2LDRpci);
+ const ARMOperand &PoolOperand =
+ static_cast<ARMOperand &>(*Operands[3]);
+ const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
+ const MCExpr *CPLoc =
+ getTargetStreamer().addConstantPoolEntry(SubExprVal,
+ PoolOperand.getStartLoc());
+ TmpInst.addOperand(Inst.getOperand(0)); // Rt
+ TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
+ if (TmpInst.getOpcode() == ARM::LDRi12)
+ TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
+ TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+ Inst = TmpInst;
+ return true;
+ }
// Handle NEON VST complex aliases.
case ARM::VST1LNdWB_register_Asm_8:
case ARM::VST1LNdWB_register_Asm_16:
More information about the llvm-commits
mailing list