diff options
author | Dale Johannesen <dalej@apple.com> | 2008-01-29 02:21:21 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2008-01-29 02:21:21 +0000 |
commit | e99fc909ce61423c2e27314675708a323e897d57 (patch) | |
tree | 3ab167b8e5d8524ae45f40e970d4c772cbb73da2 | |
parent | 0e4d4ee707d106288008353e945221a4dcfa166b (diff) | |
download | external_llvm-e99fc909ce61423c2e27314675708a323e897d57.zip external_llvm-e99fc909ce61423c2e27314675708a323e897d57.tar.gz external_llvm-e99fc909ce61423c2e27314675708a323e897d57.tar.bz2 |
Handle 'X' constraint in asm's better.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46485 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 53 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 13 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 16 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 3 |
6 files changed, 74 insertions, 21 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 003892e..40b4552 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1006,6 +1006,11 @@ public: getRegForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; + /// LowerXConstraint - try to replace an X constraint, which matches anything, + /// with another that has more specific requirements based on the type of the + /// corresponding operand. + virtual void lowerXConstraint(MVT::ValueType ConstraintVT, + std::string&) const; /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 7c4a8e1..2b83588 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -1108,9 +1108,10 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { // Disassemble the AsmStr, printing out the literal pieces, the operands, etc. const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); - // If this asmstr is empty, don't bother printing the #APP/#NOAPP markers. + // If this asmstr is empty, just print the #APP/#NOAPP markers. + // These are useful to see where empty asm's wound up. if (AsmStr[0] == 0) { - O << "\n"; // Tab already printed, avoid double indenting next instr. + O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << "\n"; return; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4b88f78..406011a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3250,27 +3250,41 @@ void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) { if (Codes.size() == 1) { // Single-letter constraints ('r') are very common. ConstraintCode = *Current; ConstraintType = CurType; - return; + } else { + unsigned CurGenerality = getConstraintGenerality(CurType); + + // If we have multiple constraints, try to pick the most general one ahead + // of time. This isn't a wonderful solution, but handles common cases. + for (unsigned j = 1, e = Codes.size(); j != e; ++j) { + TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]); + unsigned ThisGenerality = getConstraintGenerality(ThisType); + if (ThisGenerality > CurGenerality) { + // This constraint letter is more general than the previous one, + // use it. + CurType = ThisType; + Current = &Codes[j]; + CurGenerality = ThisGenerality; + } + } + + ConstraintCode = *Current; + ConstraintType = CurType; } - - unsigned CurGenerality = getConstraintGenerality(CurType); - - // If we have multiple constraints, try to pick the most general one ahead - // of time. This isn't a wonderful solution, but handles common cases. - for (unsigned j = 1, e = Codes.size(); j != e; ++j) { - TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]); - unsigned ThisGenerality = getConstraintGenerality(ThisType); - if (ThisGenerality > CurGenerality) { - // This constraint letter is more general than the previous one, - // use it. - CurType = ThisType; - Current = &Codes[j]; - CurGenerality = ThisGenerality; + + if (ConstraintCode == "X") { + if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal)) + return; + // This matches anything. Labels and constants we handle elsewhere + // ('X' is the only thing that matches labels). Otherwise, try to + // resolve it to something we know about by looking at the actual + // operand type. + std::string s = ""; + TLI.lowerXConstraint(ConstraintVT, s); + if (s!="") { + ConstraintCode = s; + ConstraintType = TLI.getConstraintType(ConstraintCode); } } - - ConstraintCode = *Current; - ConstraintType = CurType; } @@ -3492,7 +3506,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { if (OpInfo.CallOperandVal) { if (isa<BasicBlock>(OpInfo.CallOperandVal)) OpInfo.CallOperand = - DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]); + DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>( + OpInfo.CallOperandVal)]); else { OpInfo.CallOperand = getValue(OpInfo.CallOperandVal); const Type *OpTy = OpInfo.CallOperandVal->getType(); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 3ccfcfa..bd0392e 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1525,6 +1525,19 @@ TargetLowering::getConstraintType(const std::string &Constraint) const { return C_Unknown; } +/// LowerXConstraint - try to replace an X constraint, which matches anything, +/// with another that has more specific requirements based on the type of the +/// corresponding operand. +void TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT, + std::string& s) const { + if (MVT::isInteger(ConstraintVT)) + s = "r"; + else if (MVT::isFloatingPoint(ConstraintVT)) + s = "f"; // works for many targets + else + s = ""; +} + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 90408c8..229810d 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5701,6 +5701,22 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const { return TargetLowering::getConstraintType(Constraint); } +/// LowerXConstraint - try to replace an X constraint, which matches anything, +/// with another that has more specific requirements based on the type of the +/// corresponding operand. +void X86TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT, + std::string& s) const { + if (MVT::isFloatingPoint(ConstraintVT)) { + if (Subtarget->hasSSE2()) + s = "Y"; + else if (Subtarget->hasSSE1()) + s = "x"; + else + s = "f"; + } else + return TargetLowering::lowerXConstraint(ConstraintVT, s); +} + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 9df3a2e..f407dfb 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -366,6 +366,9 @@ namespace llvm { getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; + virtual void lowerXConstraint(MVT::ValueType ConstraintVT, + std::string&) const; + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. virtual void LowerAsmOperandForConstraint(SDOperand Op, |