Handle 'X' constraint in asm's better.

llvm-svn: 46485
This commit is contained in:
Dale Johannesen 2008-01-29 02:21:21 +00:00
parent 86ff705c22
commit f12104ce4b
6 changed files with 74 additions and 21 deletions

View File

@ -1006,6 +1006,11 @@ public:
getRegForInlineAsmConstraint(const std::string &Constraint, getRegForInlineAsmConstraint(const std::string &Constraint,
MVT::ValueType VT) const; 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 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. /// vector. If it is invalid, don't add anything to Ops.

View File

@ -1108,9 +1108,10 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
// Disassemble the AsmStr, printing out the literal pieces, the operands, etc. // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); 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) { if (AsmStr[0] == 0) {
O << "\n"; // Tab already printed, avoid double indenting next instr. O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << "\n";
return; return;
} }

View File

@ -3250,27 +3250,41 @@ void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) {
if (Codes.size() == 1) { // Single-letter constraints ('r') are very common. if (Codes.size() == 1) { // Single-letter constraints ('r') are very common.
ConstraintCode = *Current; ConstraintCode = *Current;
ConstraintType = CurType; 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 (ConstraintCode == "X") {
if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal))
// If we have multiple constraints, try to pick the most general one ahead return;
// of time. This isn't a wonderful solution, but handles common cases. // This matches anything. Labels and constants we handle elsewhere
for (unsigned j = 1, e = Codes.size(); j != e; ++j) { // ('X' is the only thing that matches labels). Otherwise, try to
TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]); // resolve it to something we know about by looking at the actual
unsigned ThisGenerality = getConstraintGenerality(ThisType); // operand type.
if (ThisGenerality > CurGenerality) { std::string s = "";
// This constraint letter is more general than the previous one, TLI.lowerXConstraint(ConstraintVT, s);
// use it. if (s!="") {
CurType = ThisType; ConstraintCode = s;
Current = &Codes[j]; ConstraintType = TLI.getConstraintType(ConstraintCode);
CurGenerality = ThisGenerality;
} }
} }
ConstraintCode = *Current;
ConstraintType = CurType;
} }
@ -3492,7 +3506,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
if (OpInfo.CallOperandVal) { if (OpInfo.CallOperandVal) {
if (isa<BasicBlock>(OpInfo.CallOperandVal)) if (isa<BasicBlock>(OpInfo.CallOperandVal))
OpInfo.CallOperand = OpInfo.CallOperand =
DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]); DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(
OpInfo.CallOperandVal)]);
else { else {
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal); OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
const Type *OpTy = OpInfo.CallOperandVal->getType(); const Type *OpTy = OpInfo.CallOperandVal->getType();

View File

@ -1525,6 +1525,19 @@ TargetLowering::getConstraintType(const std::string &Constraint) const {
return C_Unknown; 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 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. /// vector. If it is invalid, don't add anything to Ops.
void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,

View File

@ -5701,6 +5701,22 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
return TargetLowering::getConstraintType(Constraint); 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 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. /// vector. If it is invalid, don't add anything to Ops.
void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,

View File

@ -366,6 +366,9 @@ namespace llvm {
getRegClassForInlineAsmConstraint(const std::string &Constraint, getRegClassForInlineAsmConstraint(const std::string &Constraint,
MVT::ValueType VT) const; MVT::ValueType VT) const;
virtual void lowerXConstraint(MVT::ValueType ConstraintVT,
std::string&) const;
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. /// vector. If it is invalid, don't add anything to Ops.
virtual void LowerAsmOperandForConstraint(SDOperand Op, virtual void LowerAsmOperandForConstraint(SDOperand Op,