diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-09-24 00:05:32 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-09-24 00:05:32 +0000 |
commit | da43bcf624acb56a3d77bb5ae9a02728af032613 (patch) | |
tree | dd93cba15bfa2de5c6708211ff7d67d79792c3d6 /lib/CodeGen | |
parent | dd4924c564c7a661b78b604ebf16dfef7aa62b35 (diff) |
Properly handle 'm' inline asm constraints. If a GV is being selected for the addressing mode, it requires the same logic for PIC relative addressing, etc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56526 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 22 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 8 |
2 files changed, 25 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 416d339568..9768021b19 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4629,6 +4629,22 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, bool HasEarlyClobber, // Otherwise, we couldn't allocate enough registers for this. } +/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being +/// processed uses a memory 'm' constraint. +static bool +hasInlineAsmMemConstraint(std::vector<InlineAsm::ConstraintInfo> &CInfos, + TargetLowering &TLI) { + for (unsigned i = 0, e = CInfos.size(); i != e; ++i) { + InlineAsm::ConstraintInfo &CI = CInfos[i]; + for (unsigned j = 0, ee = CI.Codes.size(); j != ee; ++j) { + TargetLowering::ConstraintType CType = TLI.getConstraintType(CI.Codes[j]); + if (CType == TargetLowering::C_Memory) + return true; + } + } + + return false; +} /// visitInlineAsm - Handle a call to an InlineAsm object. /// @@ -4652,6 +4668,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // constraint. If so, we can't let the register allocator allocate any input // registers, because it will not know to avoid the earlyclobbered output reg. bool SawEarlyClobber = false; + + bool hasMemory = hasInlineAsmMemConstraint(ConstraintInfos, TLI); unsigned ArgNo = 0; // ArgNo - The argument of the CallInst. unsigned ResNo = 0; // ResNo - The result number of the next output. @@ -4724,7 +4742,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { OpInfo.ConstraintVT = OpVT; // Compute the constraint code and ConstraintType to use. - TLI.ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, &DAG); + TLI.ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, hasMemory, &DAG); // Keep track of whether we see an earlyclobber. SawEarlyClobber |= OpInfo.isEarlyClobber; @@ -4927,7 +4945,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { std::vector<SDValue> Ops; TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0], - Ops, DAG); + hasMemory, Ops, DAG); if (Ops.empty()) { cerr << "Invalid operand for inline asm constraint '" << OpInfo.ConstraintCode << "'!\n"; diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index a85890a433..a9078b1e51 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1855,6 +1855,7 @@ const char *TargetLowering::LowerXConstraint(MVT ConstraintVT) const{ /// vector. If it is invalid, don't add anything to Ops. void TargetLowering::LowerAsmOperandForConstraint(SDValue Op, char ConstraintLetter, + bool hasMemory, std::vector<SDValue> &Ops, SelectionDAG &DAG) const { switch (ConstraintLetter) { @@ -1997,7 +1998,7 @@ static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { /// 'm' over 'r', for example. /// static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, - const TargetLowering &TLI, + bool hasMemory, const TargetLowering &TLI, SDValue Op, SelectionDAG *DAG) { assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options"); unsigned BestIdx = 0; @@ -2017,7 +2018,7 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, assert(OpInfo.Codes[i].size() == 1 && "Unhandled multi-letter 'other' constraint"); std::vector<SDValue> ResultOps; - TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0], + TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0], hasMemory, ResultOps, *DAG); if (!ResultOps.empty()) { BestType = CType; @@ -2044,6 +2045,7 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, /// OpInfo.ConstraintCode and OpInfo.ConstraintType. void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, + bool hasMemory, SelectionDAG *DAG) const { assert(!OpInfo.Codes.empty() && "Must have at least one constraint"); @@ -2052,7 +2054,7 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, OpInfo.ConstraintCode = OpInfo.Codes[0]; OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode); } else { - ChooseConstraint(OpInfo, *this, Op, DAG); + ChooseConstraint(OpInfo, hasMemory, *this, Op, DAG); } // 'X' matches anything. |