aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-01-29 02:21:21 +0000
committerDale Johannesen <dalej@apple.com>2008-01-29 02:21:21 +0000
commite99fc909ce61423c2e27314675708a323e897d57 (patch)
tree3ab167b8e5d8524ae45f40e970d4c772cbb73da2
parent0e4d4ee707d106288008353e945221a4dcfa166b (diff)
downloadexternal_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.h5
-rw-r--r--lib/CodeGen/AsmPrinter.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp53
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp13
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp16
-rw-r--r--lib/Target/X86/X86ISelLowering.h3
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,