<div class="gmail_quote">On 29 October 2010 10:29, John Thompson <span dir="ltr"><<a href="mailto:John.Thompson.JTSoftware@gmail.com">John.Thompson.JTSoftware@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Author: jtsoftware<br>
Date: Fri Oct 29 12:29:13 2010<br>
New Revision: 117667<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=117667&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=117667&view=rev</a><br>
Log:<br>
Inline asm multiple alternative constraints development phase 2 - improved basic logic, added initial platform support.<br></blockquote><div><br></div><div>This change makes SelectionDAGBuilder::visitInlineAsm use up 30k of stack space, largely due to the switch from std::vector to SmallVector. Please fix!</div>
<div><br></div><div>Nick</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Modified:<br>
llvm/trunk/include/llvm/CodeGen/Analysis.h<br>
llvm/trunk/include/llvm/InlineAsm.h<br>
llvm/trunk/include/llvm/Target/TargetLowering.h<br>
llvm/trunk/lib/CodeGen/Analysis.cpp<br>
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp<br>
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
llvm/trunk/lib/Target/ARM/ARMISelLowering.h<br>
llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp<br>
llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h<br>
llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp<br>
llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h<br>
llvm/trunk/lib/Target/CBackend/CBackend.cpp<br>
llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp<br>
llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h<br>
llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp<br>
llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h<br>
llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp<br>
llvm/trunk/lib/Target/Mips/MipsISelLowering.h<br>
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h<br>
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp<br>
llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp<br>
llvm/trunk/lib/VMCore/InlineAsm.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/Analysis.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Analysis.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Analysis.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/Analysis.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/Analysis.h Fri Oct 29 12:29:13 2010<br>
@@ -52,7 +52,7 @@<br>
<br>
/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being<br>
/// processed uses a memory 'm' constraint.<br>
-bool hasInlineAsmMemConstraint(std::vector<InlineAsm::ConstraintInfo> &CInfos,<br>
+bool hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos,<br>
const TargetLowering &TLI);<br>
<br>
/// getFCmpCondCode - Return the ISD condition code corresponding to<br>
<br>
Modified: llvm/trunk/include/llvm/InlineAsm.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/InlineAsm.h (original)<br>
+++ llvm/trunk/include/llvm/InlineAsm.h Fri Oct 29 12:29:13 2010<br>
@@ -16,8 +16,8 @@<br>
#ifndef LLVM_INLINEASM_H<br>
#define LLVM_INLINEASM_H<br>
<br>
+#include "llvm/ADT/SmallVector.h"<br>
#include "llvm/Value.h"<br>
-#include <vector><br>
<br>
namespace llvm {<br>
<br>
@@ -87,6 +87,8 @@<br>
isClobber // '~x'<br>
};<br>
<br>
+ typedef SmallVector<std::string,8> ConstraintCodeVector;<br>
+<br>
struct SubConstraintInfo {<br>
/// MatchingInput - If this is not -1, this is an output constraint where an<br>
/// input constraint is required to match it (e.g. "0"). The value is the<br>
@@ -95,10 +97,14 @@<br>
signed char MatchingInput;<br>
/// Code - The constraint code, either the register name (in braces) or the<br>
/// constraint letter/number.<br>
- std::vector<std::string> Codes;<br>
+ ConstraintCodeVector Codes;<br>
/// Default constructor.<br>
SubConstraintInfo() : MatchingInput(-1) {}<br>
};<br>
+<br>
+ typedef SmallVector<SubConstraintInfo,4> SubConstraintInfoVector;<br>
+ struct ConstraintInfo;<br>
+ typedef SmallVector<ConstraintInfo,16> ConstraintInfoVector;<br>
<br>
struct ConstraintInfo {<br>
/// Type - The basic type of the constraint: input/output/clobber<br>
@@ -131,14 +137,14 @@<br>
<br>
/// Code - The constraint code, either the register name (in braces) or the<br>
/// constraint letter/number.<br>
- std::vector<std::string> Codes;<br>
+ ConstraintCodeVector Codes;<br>
<br>
/// isMultipleAlternative - '|': has multiple-alternative constraints.<br>
bool isMultipleAlternative;<br>
<br>
/// multipleAlternatives - If there are multiple alternative constraints,<br>
/// this array will contain them. Otherwise it will be empty.<br>
- std::vector<SubConstraintInfo> multipleAlternatives;<br>
+ SubConstraintInfoVector multipleAlternatives;<br>
<br>
/// The currently selected alternative constraint index.<br>
unsigned currentAlternativeIndex;<br>
@@ -152,8 +158,7 @@<br>
/// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the<br>
/// fields in this structure. If the constraint string is not understood,<br>
/// return true, otherwise return false.<br>
- bool Parse(StringRef Str,<br>
- std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar);<br>
+ bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);<br>
<br>
/// selectAlternative - Point this constraint to the alternative constraint<br>
/// indicated by the index.<br>
@@ -163,13 +168,11 @@<br>
/// ParseConstraints - Split up the constraint string into the specific<br>
/// constraints and their prefixes. If this returns an empty vector, and if<br>
/// the constraint string itself isn't empty, there was an error parsing.<br>
- static std::vector<ConstraintInfo><br>
- ParseConstraints(StringRef ConstraintString);<br>
+ static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);<br>
<br>
/// ParseConstraints - Parse the constraints of this inlineasm object,<br>
/// returning them the same way that ParseConstraints(str) does.<br>
- std::vector<ConstraintInfo><br>
- ParseConstraints() const {<br>
+ ConstraintInfoVector ParseConstraints() const {<br>
return ParseConstraints(Constraints);<br>
}<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)<br>
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -1320,6 +1320,22 @@<br>
C_Unknown // Unsupported constraint.<br>
};<br>
<br>
+ enum ConstraintWeight {<br>
+ // Generic weights.<br>
+ CW_Invalid = -1, // No match.<br>
+ CW_Okay = 0, // Acceptable.<br>
+ CW_Good = 1, // Good weight.<br>
+ CW_Better = 2, // Better weight.<br>
+ CW_Best = 3, // Best weight.<br>
+<br>
+ // Well-known weights.<br>
+ CW_SpecificReg = CW_Okay, // Specific register operands.<br>
+ CW_Register = CW_Good, // Register operands.<br>
+ CW_Memory = CW_Better, // Memory operands.<br>
+ CW_Constant = CW_Best, // Constant operand.<br>
+ CW_Default = CW_Okay // Default or don't know type.<br>
+ };<br>
+<br>
/// AsmOperandInfo - This contains information for each constraint that we are<br>
/// lowering.<br>
struct AsmOperandInfo : public InlineAsm::ConstraintInfo {<br>
@@ -1365,24 +1381,23 @@<br>
}<br>
};<br>
<br>
+ typedef SmallVector<AsmOperandInfo,16> AsmOperandInfoVector;<br>
+<br>
/// ParseConstraints - Split up the constraint string from the inline<br>
/// assembly value into the specific constraints and their prefixes,<br>
/// and also tie in the associated operand values.<br>
/// If this returns an empty vector, and if the constraint string itself<br>
/// isn't empty, there was an error parsing.<br>
- virtual std::vector<AsmOperandInfo> ParseConstraints(<br>
- ImmutableCallSite CS) const;<br>
+ virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;<br>
<br>
- /// Examine constraint type and operand type and determine a weight value,<br>
- /// where: -1 = invalid match, and 0 = so-so match to 5 = good match.<br>
+ /// Examine constraint type and operand type and determine a weight value.<br>
/// The operand object must already have been set up with the operand type.<br>
- virtual int getMultipleConstraintMatchWeight(<br>
+ virtual ConstraintWeight getMultipleConstraintMatchWeight(<br>
AsmOperandInfo &info, int maIndex) const;<br>
<br>
- /// Examine constraint string and operand type and determine a weight value,<br>
- /// where: -1 = invalid match, and 0 = so-so match to 3 = good match.<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
/// The operand object must already have been set up with the operand type.<br>
- virtual int getSingleConstraintMatchWeight(<br>
+ virtual ConstraintWeight getSingleConstraintMatchWeight(<br>
AsmOperandInfo &info, const char *constraint) const;<br>
<br>
/// ComputeConstraintToUse - Determines the constraint code and constraint<br>
<br>
Modified: llvm/trunk/lib/CodeGen/Analysis.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/Analysis.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/Analysis.cpp Fri Oct 29 12:29:13 2010<br>
@@ -125,7 +125,7 @@<br>
/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being<br>
/// processed uses a memory 'm' constraint.<br>
bool<br>
-llvm::hasInlineAsmMemConstraint(std::vector<InlineAsm::ConstraintInfo> &CInfos,<br>
+llvm::hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos,<br>
const TargetLowering &TLI) {<br>
for (unsigned i = 0, e = CInfos.size(); i != e; ++i) {<br>
InlineAsm::ConstraintInfo &CI = CInfos[i];<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Oct 29 12:29:13 2010<br>
@@ -5221,6 +5221,8 @@<br>
}<br>
};<br>
<br>
+typedef SmallVector<SDISelAsmOperandInfo,16> SDISelAsmOperandInfoVector;<br>
+<br>
} // end llvm namespace.<br>
<br>
/// isAllocatableRegister - If the specified register is safe to allocate,<br>
@@ -5458,11 +5460,11 @@<br>
const InlineAsm *IA = cast<InlineAsm>(CS.getCalledValue());<br>
<br>
/// ConstraintOperands - Information about all of the constraints.<br>
- std::vector<SDISelAsmOperandInfo> ConstraintOperands;<br>
+ SDISelAsmOperandInfoVector ConstraintOperands;<br>
<br>
std::set<unsigned> OutputRegs, InputRegs;<br>
<br>
- std::vector<TargetLowering::AsmOperandInfo> TargetConstraints = TLI.ParseConstraints(CS);<br>
+ TargetLowering::AsmOperandInfoVector TargetConstraints = TLI.ParseConstraints(CS);<br>
bool hasMemory = false;<br>
<br>
unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -2664,16 +2664,16 @@<br>
/// and also tie in the associated operand values.<br>
/// If this returns an empty vector, and if the constraint string itself<br>
/// isn't empty, there was an error parsing.<br>
-std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(<br>
+TargetLowering::AsmOperandInfoVector TargetLowering::ParseConstraints(<br>
ImmutableCallSite CS) const {<br>
/// ConstraintOperands - Information about all of the constraints.<br>
- std::vector<AsmOperandInfo> ConstraintOperands;<br>
+ AsmOperandInfoVector ConstraintOperands;<br>
const InlineAsm *IA = cast<InlineAsm>(CS.getCalledValue());<br>
unsigned maCount = 0; // Largest number of multiple alternative constraints.<br>
<br>
// Do a prepass over the constraints, canonicalizing them, and building up the<br>
// ConstraintOperands list.<br>
- std::vector<InlineAsm::ConstraintInfo><br>
+ InlineAsm::ConstraintInfoVector<br>
ConstraintInfos = IA->ParseConstraints();<br>
<br>
unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.<br>
@@ -2687,7 +2687,7 @@<br>
if (OpInfo.multipleAlternatives.size() > maCount)<br>
maCount = OpInfo.multipleAlternatives.size();<br>
<br>
- EVT OpVT = MVT::Other;<br>
+ OpInfo.ConstraintVT = MVT::Other;<br>
<br>
// Compute the value type for each operand.<br>
switch (OpInfo.Type) {<br>
@@ -2703,10 +2703,10 @@<br>
assert(!CS.getType()->isVoidTy() &&<br>
"Bad inline asm!");<br>
if (const StructType *STy = dyn_cast<StructType>(CS.getType())) {<br>
- OpVT = getValueType(STy->getElementType(ResNo));<br>
+ OpInfo.ConstraintVT = getValueType(STy->getElementType(ResNo));<br>
} else {<br>
assert(ResNo == 0 && "Asm only has one result!");<br>
- OpVT = getValueType(CS.getType());<br>
+ OpInfo.ConstraintVT = getValueType(CS.getType());<br>
}<br>
++ResNo;<br>
break;<br>
@@ -2717,6 +2717,36 @@<br>
// Nothing to do.<br>
break;<br>
}<br>
+<br>
+ if (OpInfo.CallOperandVal) {<br>
+ const llvm::Type *OpTy = OpInfo.CallOperandVal->getType();<br>
+ if (OpInfo.isIndirect) {<br>
+ const llvm::PointerType *PtrTy = dyn_cast<PointerType>(OpTy);<br>
+ if (!PtrTy)<br>
+ report_fatal_error("Indirect operand for inline asm not a pointer!");<br>
+ OpTy = PtrTy->getElementType();<br>
+ }<br>
+ // If OpTy is not a single value, it may be a struct/union that we<br>
+ // can tile with integers.<br>
+ if (!OpTy->isSingleValueType() && OpTy->isSized()) {<br>
+ unsigned BitSize = TD->getTypeSizeInBits(OpTy);<br>
+ switch (BitSize) {<br>
+ default: break;<br>
+ case 1:<br>
+ case 8:<br>
+ case 16:<br>
+ case 32:<br>
+ case 64:<br>
+ case 128:<br>
+ OpTy = IntegerType::get(OpTy->getContext(), BitSize);<br>
+ break;<br>
+ }<br>
+ } else if (dyn_cast<PointerType>(OpTy)) {<br>
+ OpInfo.ConstraintVT = MVT::getIntegerVT(8*TD->getPointerSize());<br>
+ } else {<br>
+ OpInfo.ConstraintVT = EVT::getEVT(OpTy, true);<br>
+ }<br>
+ }<br>
}<br>
<br>
// If we have multiple alternative constraints, select the best alternative.<br>
@@ -2737,13 +2767,12 @@<br>
if (OpInfo.Type == InlineAsm::isClobber)<br>
continue;<br>
<br>
- // If this is an output operand with a matching input operand, look up the<br>
- // matching input. If their types mismatch, e.g. one is an integer, the<br>
- // other is floating point, or their sizes are different, flag it as an<br>
- // maCantMatch.<br>
+ // If this is an output operand with a matching input operand,<br>
+ // look up the matching input. If their types mismatch, e.g. one<br>
+ // is an integer, the other is floating point, or their sizes are<br>
+ // different, flag it as an maCantMatch.<br>
if (OpInfo.hasMatchingInput()) {<br>
AsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput];<br>
-<br>
if (OpInfo.ConstraintVT != Input.ConstraintVT) {<br>
if ((OpInfo.ConstraintVT.isInteger() !=<br>
Input.ConstraintVT.isInteger()) ||<br>
@@ -2752,10 +2781,8 @@<br>
weightSum = -1; // Can't match.<br>
break;<br>
}<br>
- Input.ConstraintVT = OpInfo.ConstraintVT;<br>
}<br>
}<br>
-<br>
weight = getMultipleConstraintMatchWeight(OpInfo, maIndex);<br>
if (weight == -1) {<br>
weightSum = -1;<br>
@@ -2792,7 +2819,7 @@<br>
// error.<br>
if (OpInfo.hasMatchingInput()) {<br>
AsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput];<br>
-<br>
+<br>
if (OpInfo.ConstraintVT != Input.ConstraintVT) {<br>
if ((OpInfo.ConstraintVT.isInteger() !=<br>
Input.ConstraintVT.isInteger()) ||<br>
@@ -2802,8 +2829,8 @@<br>
" with a matching output constraint of"<br>
" incompatible type!");<br>
}<br>
- Input.ConstraintVT = OpInfo.ConstraintVT;<br>
}<br>
+<br>
}<br>
}<br>
<br>
@@ -2828,22 +2855,23 @@<br>
}<br>
}<br>
<br>
-/// Examine constraint type and operand type and determine a weight value,<br>
-/// where: -1 = invalid match, and 0 = so-so match to 3 = good match.<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
/// This object must already have been set up with the operand type<br>
/// and the current alternative constraint selected.<br>
-int TargetLowering::getMultipleConstraintMatchWeight(<br>
+TargetLowering::ConstraintWeight<br>
+ TargetLowering::getMultipleConstraintMatchWeight(<br>
AsmOperandInfo &info, int maIndex) const {<br>
- std::vector<std::string> *rCodes;<br>
+ InlineAsm::ConstraintCodeVector *rCodes;<br>
if (maIndex >= (int)info.multipleAlternatives.size())<br>
rCodes = &info.Codes;<br>
else<br>
rCodes = &info.multipleAlternatives[maIndex].Codes;<br>
- int BestWeight = -1;<br>
+ ConstraintWeight BestWeight = CW_Invalid;<br>
<br>
// Loop over the options, keeping track of the most general one.<br>
for (unsigned i = 0, e = rCodes->size(); i != e; ++i) {<br>
- int weight = getSingleConstraintMatchWeight(info, (*rCodes)[i].c_str());<br>
+ ConstraintWeight weight =<br>
+ getSingleConstraintMatchWeight(info, (*rCodes)[i].c_str());<br>
if (weight > BestWeight)<br>
BestWeight = weight;<br>
}<br>
@@ -2851,50 +2879,50 @@<br>
return BestWeight;<br>
}<br>
<br>
-/// Examine constraint type and operand type and determine a weight value,<br>
-/// where: -1 = invalid match, and 0 = so-so match to 3 = good match.<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
/// This object must already have been set up with the operand type<br>
/// and the current alternative constraint selected.<br>
-int TargetLowering::getSingleConstraintMatchWeight(<br>
+TargetLowering::ConstraintWeight<br>
+ TargetLowering::getSingleConstraintMatchWeight(<br>
AsmOperandInfo &info, const char *constraint) const {<br>
- int weight = -1;<br>
+ ConstraintWeight weight = CW_Invalid;<br>
Value *CallOperandVal = info.CallOperandVal;<br>
// If we don't have a value, we can't do a match,<br>
// but allow it at the lowest weight.<br>
if (CallOperandVal == NULL)<br>
- return 0;<br>
+ return CW_Default;<br>
// Look at the constraint type.<br>
switch (*constraint) {<br>
case 'i': // immediate integer.<br>
case 'n': // immediate integer with a known value.<br>
- weight = 0;<br>
- if (info.CallOperandVal) {<br>
- if (isa<ConstantInt>(info.CallOperandVal))<br>
- weight = 3;<br>
- else<br>
- weight = -1;<br>
- }<br>
+ if (isa<ConstantInt>(CallOperandVal))<br>
+ weight = CW_Constant;<br>
break;<br>
case 's': // non-explicit intregal immediate.<br>
- weight = 0;<br>
- if (info.CallOperandVal) {<br>
- if (isa<GlobalValue>(info.CallOperandVal))<br>
- weight = 3;<br>
- else<br>
- weight = -1;<br>
- }<br>
+ if (isa<GlobalValue>(CallOperandVal))<br>
+ weight = CW_Constant;<br>
break;<br>
+ case 'E': // immediate float if host format.<br>
+ case 'F': // immediate float.<br>
+ if (isa<ConstantFP>(CallOperandVal))<br>
+ weight = CW_Constant;<br>
+ break;<br>
+ case '<': // memory operand with autodecrement.<br>
+ case '>': // memory operand with autoincrement.<br>
case 'm': // memory operand.<br>
case 'o': // offsettable memory operand<br>
case 'V': // non-offsettable memory operand<br>
- weight = 2;<br>
+ weight = CW_Memory;<br>
break;<br>
+ case 'r': // general register.<br>
case 'g': // general register, memory operand or immediate integer.<br>
- case 'X': // any operand.<br>
- weight = 1;<br>
+ // note: Clang converts "g" to "imr".<br>
+ if (CallOperandVal->getType()->isIntegerTy())<br>
+ weight = CW_Register;<br>
break;<br>
+ case 'X': // any operand.<br>
default:<br>
- weight = 0;<br>
+ weight = CW_Default;<br>
break;<br>
}<br>
return weight;<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -5441,6 +5441,40 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+ARMTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ const Type *type = CallOperandVal->getType();<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ case 'l':<br>
+ if (type->isIntegerTy()) {<br>
+ if (Subtarget->isThumb())<br>
+ weight = CW_SpecificReg;<br>
+ else<br>
+ weight = CW_Register;<br>
+ }<br>
+ break;<br>
+ case 'w':<br>
+ if (type->isFloatingPointTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const {<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -241,6 +241,12 @@<br>
<br>
<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
+<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -27,6 +27,7 @@<br>
#include "llvm/Function.h"<br>
#include "llvm/Module.h"<br>
#include "llvm/Intrinsics.h"<br>
+#include "llvm/Type.h"<br>
#include "llvm/Support/CommandLine.h"<br>
#include "llvm/Support/ErrorHandling.h"<br>
#include "llvm/Support/raw_ostream.h"<br>
@@ -803,6 +804,30 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+AlphaTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ case 'f':<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
std::vector<unsigned> AlphaTargetLowering::<br>
getRegClassForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const {<br>
<br>
Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -87,6 +87,11 @@<br>
<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::vector<unsigned><br>
getRegClassForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -15,6 +15,7 @@<br>
#include "BlackfinISelLowering.h"<br>
#include "BlackfinTargetMachine.h"<br>
#include "llvm/Function.h"<br>
+#include "llvm/Type.h"<br>
#include "llvm/CodeGen/CallingConvLower.h"<br>
#include "llvm/CodeGen/MachineFrameInfo.h"<br>
#include "llvm/CodeGen/MachineFunction.h"<br>
@@ -549,6 +550,52 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+BlackfinTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+<br>
+ // Blackfin-specific constraints<br>
+ case 'a':<br>
+ case 'd':<br>
+ case 'z':<br>
+ case 'D':<br>
+ case 'W':<br>
+ case 'e':<br>
+ case 'b':<br>
+ case 'v':<br>
+ case 'f':<br>
+ case 'c':<br>
+ case 't':<br>
+ case 'u':<br>
+ case 'k':<br>
+ case 'x':<br>
+ case 'y':<br>
+ case 'w':<br>
+ return CW_Register;<br>
+ case 'A':<br>
+ case 'B':<br>
+ case 'C':<br>
+ case 'Z':<br>
+ case 'Y':<br>
+ return CW_SpecificReg;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
/// getRegForInlineAsmConstraint - Return register no and class for a C_Register<br>
/// constraint.<br>
std::pair<unsigned, const TargetRegisterClass*> BlackfinTargetLowering::<br>
<br>
Modified: llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -39,6 +39,12 @@<br>
SelectionDAG &DAG) const;<br>
<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
+<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const;<br>
std::vector<unsigned><br>
<br>
Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)<br>
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Fri Oct 29 12:29:13 2010<br>
@@ -3193,7 +3193,7 @@<br>
// handle communitivity<br>
void CWriter::visitInlineAsm(CallInst &CI) {<br>
InlineAsm* as = cast<InlineAsm>(CI.getCalledValue());<br>
- std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints();<br>
+ InlineAsm::ConstraintInfoVector Constraints = as->ParseConstraints();<br>
<br>
std::vector<std::pair<Value*, int> > ResultVals;<br>
if (CI.getType() == Type::getVoidTy(CI.getContext()))<br>
@@ -3213,7 +3213,7 @@<br>
bool IsFirst = true;<br>
<br>
// Convert over all the output constraints.<br>
- for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),<br>
+ for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),<br>
E = Constraints.end(); I != E; ++I) {<br>
<br>
if (I->Type != InlineAsm::isOutput) {<br>
@@ -3255,7 +3255,7 @@<br>
Out << "\n :";<br>
IsFirst = true;<br>
ValueCount = 0;<br>
- for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),<br>
+ for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),<br>
E = Constraints.end(); I != E; ++I) {<br>
if (I->Type != InlineAsm::isInput) {<br>
++ValueCount;<br>
@@ -3284,7 +3284,7 @@<br>
<br>
// Convert over the clobber constraints.<br>
IsFirst = true;<br>
- for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),<br>
+ for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),<br>
E = Constraints.end(); I != E; ++I) {<br>
if (I->Type != InlineAsm::isClobber)<br>
continue; // Ignore non-input constraints.<br>
<br>
Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -20,6 +20,7 @@<br>
#include "llvm/Function.h"<br>
#include "llvm/Intrinsics.h"<br>
#include "llvm/CallingConv.h"<br>
+#include "llvm/Type.h"<br>
#include "llvm/CodeGen/CallingConvLower.h"<br>
#include "llvm/CodeGen/MachineFrameInfo.h"<br>
#include "llvm/CodeGen/MachineFunction.h"<br>
@@ -2989,6 +2990,38 @@<br>
return TargetLowering::getConstraintType(ConstraintLetter);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+SPUTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ //FIXME: Seems like the supported constraint letters were just copied<br>
+ // from PPC, as the following doesn't correspond to the GCC docs.<br>
+ // I'm leaving it so until someone adds the corresponding lowering support.<br>
+ case 'b':<br>
+ case 'r':<br>
+ case 'f':<br>
+ case 'd':<br>
+ case 'v':<br>
+ case 'y':<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const<br>
<br>
Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -129,6 +129,11 @@<br>
<br>
ConstraintType getConstraintType(const std::string &ConstraintLetter) const;<br>
<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -908,6 +908,37 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+MBlazeTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ const Type *type = CallOperandVal->getType();<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ case 'd':<br>
+ case 'y':<br>
+ if (type->isIntegerTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'f':<br>
+ if (type->isFloatTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
/// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),<br>
/// return a list of registers that can be used to satisfy the constraint.<br>
/// This should only be used for C_RegisterClass constraints.<br>
<br>
Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -153,6 +153,11 @@<br>
// Inline asm support<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -1269,6 +1269,37 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+MipsTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ const Type *type = CallOperandVal->getType();<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ case 'd':<br>
+ case 'y':<br>
+ if (type->isIntegerTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'f':<br>
+ if (type->isFloatTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
/// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),<br>
/// return a list of registers that can be used to satisfy the constraint.<br>
/// This should only be used for C_RegisterClass constraints.<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -139,6 +139,11 @@<br>
// Inline asm support<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -2473,13 +2473,13 @@<br>
// node so that legalize doesn't hack it.<br>
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {<br>
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,<br>
- Callee.getValueType());<br>
+ Callee.getValueType());<br>
needIndirectCall = false;<br>
}<br>
}<br>
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {<br>
Callee = DAG.getTargetExternalSymbol(S->getSymbol(),<br>
- Callee.getValueType());<br>
+ Callee.getValueType());<br>
needIndirectCall = false;<br>
}<br>
if (needIndirectCall) {<br>
@@ -5374,6 +5374,47 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
+/// This object must already have been set up with the operand type<br>
+/// and the current alternative constraint selected.<br>
+TargetLowering::ConstraintWeight<br>
+PPCTargetLowering::getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const {<br>
+ ConstraintWeight weight = CW_Invalid;<br>
+ Value *CallOperandVal = info.CallOperandVal;<br>
+ // If we don't have a value, we can't do a match,<br>
+ // but allow it at the lowest weight.<br>
+ if (CallOperandVal == NULL)<br>
+ return CW_Default;<br>
+ const Type *type = CallOperandVal->getType();<br>
+ // Look at the constraint type.<br>
+ switch (*constraint) {<br>
+ default:<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ break;<br>
+ case 'b':<br>
+ if (type->isIntegerTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'f':<br>
+ if (type->isFloatTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'd':<br>
+ if (type->isDoubleTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'v':<br>
+ if (type->isVectorTy())<br>
+ weight = CW_Register;<br>
+ break;<br>
+ case 'y':<br>
+ weight = CW_Register;<br>
+ break;<br>
+ }<br>
+ return weight;<br>
+}<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const {<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -308,6 +308,12 @@<br>
bool is8bit, unsigned Opcode) const;<br>
<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
+<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
+ /// The operand object must already have been set up with the operand type.<br>
+ ConstraintWeight getSingleConstraintMatchWeight(<br>
+ AsmOperandInfo &info, const char *constraint) const;<br>
+<br>
std::pair<unsigned, const TargetRegisterClass*><br>
getRegForInlineAsmConstraint(const std::string &Constraint,<br>
EVT VT) const;<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Oct 29 12:29:13 2010<br>
@@ -11428,7 +11428,7 @@<br>
<br>
bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {<br>
InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());<br>
- std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();<br>
+ InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();<br>
<br>
std::string AsmStr = IA->getAsmString();<br>
<br>
@@ -11508,18 +11508,32 @@<br>
X86TargetLowering::getConstraintType(const std::string &Constraint) const {<br>
if (Constraint.size() == 1) {<br>
switch (Constraint[0]) {<br>
- case 'A':<br>
- return C_Register;<br>
- case 'f':<br>
- case 'r':<br>
case 'R':<br>
- case 'l':<br>
case 'q':<br>
case 'Q':<br>
- case 'x':<br>
+ case 'f':<br>
+ case 't':<br>
+ case 'u':<br>
case 'y':<br>
+ case 'x':<br>
case 'Y':<br>
return C_RegisterClass;<br>
+ case 'a':<br>
+ case 'b':<br>
+ case 'c':<br>
+ case 'd':<br>
+ case 'S':<br>
+ case 'D':<br>
+ case 'A':<br>
+ return C_Register;<br>
+ case 'I':<br>
+ case 'J':<br>
+ case 'K':<br>
+ case 'L':<br>
+ case 'M':<br>
+ case 'N':<br>
+ case 'G':<br>
+ case 'C':<br>
case 'e':<br>
case 'Z':<br>
return C_Other;<br>
@@ -11530,30 +11544,106 @@<br>
return TargetLowering::getConstraintType(Constraint);<br>
}<br>
<br>
-/// Examine constraint type and operand type and determine a weight value,<br>
-/// where: -1 = invalid match, and 0 = so-so match to 3 = good match.<br>
+/// Examine constraint type and operand type and determine a weight value.<br>
/// This object must already have been set up with the operand type<br>
/// and the current alternative constraint selected.<br>
-int X86TargetLowering::getSingleConstraintMatchWeight(<br>
+TargetLowering::ConstraintWeight<br>
+ X86TargetLowering::getSingleConstraintMatchWeight(<br>
AsmOperandInfo &info, const char *constraint) const {<br>
- int weight = -1;<br>
+ ConstraintWeight weight = CW_Invalid;<br>
Value *CallOperandVal = info.CallOperandVal;<br>
// If we don't have a value, we can't do a match,<br>
// but allow it at the lowest weight.<br>
if (CallOperandVal == NULL)<br>
- return 0;<br>
+ return CW_Default;<br>
+ const Type *type = CallOperandVal->getType();<br>
// Look at the constraint type.<br>
switch (*constraint) {<br>
default:<br>
- return TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);<br>
+ case 'R':<br>
+ case 'q':<br>
+ case 'Q':<br>
+ case 'a':<br>
+ case 'b':<br>
+ case 'c':<br>
+ case 'd':<br>
+ case 'S':<br>
+ case 'D':<br>
+ case 'A':<br>
+ if (CallOperandVal->getType()->isIntegerTy())<br>
+ weight = CW_SpecificReg;<br>
+ break;<br>
+ case 'f':<br>
+ case 't':<br>
+ case 'u':<br>
+ if (type->isFloatingPointTy())<br>
+ weight = CW_SpecificReg;<br>
+ break;<br>
+ case 'y':<br>
+ if (type->isX86_MMXTy() && !DisableMMX && Subtarget->hasMMX())<br>
+ weight = CW_SpecificReg;<br>
+ break;<br>
+ case 'x':<br>
+ case 'Y':<br>
+ if ((type->getPrimitiveSizeInBits() == 128) && Subtarget->hasSSE1())<br>
+ weight = CW_Register;<br>
break;<br>
case 'I':<br>
if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {<br>
if (C->getZExtValue() <= 31)<br>
- weight = 3;<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'J':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if (C->getZExtValue() <= 63)<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'K':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if ((C->getSExtValue() >= -0x80) && (C->getSExtValue() <= 0x7f))<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'L':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if ((C->getZExtValue() == 0xff) || (C->getZExtValue() == 0xffff))<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'M':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if (C->getZExtValue() <= 3)<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'N':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if (C->getZExtValue() <= 0xff)<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'G':<br>
+ case 'C':<br>
+ if (dyn_cast<ConstantFP>(CallOperandVal)) {<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'e':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if ((C->getSExtValue() >= -0x80000000LL) &&<br>
+ (C->getSExtValue() <= 0x7fffffffLL))<br>
+ weight = CW_Constant;<br>
+ }<br>
+ break;<br>
+ case 'Z':<br>
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {<br>
+ if (C->getZExtValue() <= 0xffffffff)<br>
+ weight = CW_Constant;<br>
}<br>
break;<br>
- // etc.<br>
}<br>
return weight;<br>
}<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Oct 29 12:29:13 2010<br>
@@ -542,10 +542,9 @@<br>
<br>
ConstraintType getConstraintType(const std::string &Constraint) const;<br>
<br>
- /// Examine constraint string and operand type and determine a weight value,<br>
- /// where: -1 = invalid match, and 0 = so-so match to 3 = good match.<br>
+ /// Examine constraint string and operand type and determine a weight value.<br>
/// The operand object must already have been set up with the operand type.<br>
- virtual int getSingleConstraintMatchWeight(<br>
+ virtual ConstraintWeight getSingleConstraintMatchWeight(<br>
AsmOperandInfo &info, const char *constraint) const;<br>
<br>
std::vector<unsigned><br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Fri Oct 29 12:29:13 2010<br>
@@ -743,7 +743,7 @@<br>
DenseMap<Value*,Value*> &SunkAddrs) {<br>
bool MadeChange = false;<br>
<br>
- std::vector<TargetLowering::AsmOperandInfo> TargetConstraints = TLI->ParseConstraints(CS);<br>
+ TargetLowering::AsmOperandInfoVector TargetConstraints = TLI->ParseConstraints(CS);<br>
unsigned ArgNo = 0;<br>
for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) {<br>
TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i];<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp Fri Oct 29 12:29:13 2010<br>
@@ -380,7 +380,7 @@<br>
/// return false.<br>
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal,<br>
const TargetLowering &TLI) {<br>
- std::vector<TargetLowering::AsmOperandInfo> TargetConstraints = TLI.ParseConstraints(ImmutableCallSite(CI));<br>
+ TargetLowering::AsmOperandInfoVector TargetConstraints = TLI.ParseConstraints(ImmutableCallSite(CI));<br>
for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) {<br>
TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i];<br>
<br>
<br>
Modified: llvm/trunk/lib/VMCore/InlineAsm.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/InlineAsm.cpp?rev=117667&r1=117666&r2=117667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/InlineAsm.cpp?rev=117667&r1=117666&r2=117667&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/VMCore/InlineAsm.cpp (original)<br>
+++ llvm/trunk/lib/VMCore/InlineAsm.cpp Fri Oct 29 12:29:13 2010<br>
@@ -76,11 +76,11 @@<br>
/// fields in this structure. If the constraint string is not understood,<br>
/// return true, otherwise return false.<br>
bool InlineAsm::ConstraintInfo::Parse(StringRef Str,<br>
- std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) {<br>
+ InlineAsm::ConstraintInfoVector &ConstraintsSoFar) {<br>
StringRef::iterator I = Str.begin(), E = Str.end();<br>
unsigned multipleAlternativeCount = Str.count('|') + 1;<br>
unsigned multipleAlternativeIndex = 0;<br>
- std::vector<std::string> *pCodes = &Codes;<br>
+ ConstraintCodeVector *pCodes = &Codes;<br>
<br>
// Initialize<br>
isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false);<br>
@@ -202,9 +202,9 @@<br>
}<br>
}<br>
<br>
-std::vector<InlineAsm::ConstraintInfo><br>
+InlineAsm::ConstraintInfoVector<br>
InlineAsm::ParseConstraints(StringRef Constraints) {<br>
- std::vector<ConstraintInfo> Result;<br>
+ ConstraintInfoVector Result;<br>
<br>
// Scan the constraints string.<br>
for (StringRef::iterator I = Constraints.begin(),<br>
@@ -239,7 +239,7 @@<br>
bool InlineAsm::Verify(const FunctionType *Ty, StringRef ConstStr) {<br>
if (Ty->isVarArg()) return false;<br>
<br>
- std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr);<br>
+ ConstraintInfoVector Constraints = ParseConstraints(ConstStr);<br>
<br>
// Error parsing constraints.<br>
if (Constraints.empty() && !ConstStr.empty()) return false;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>