<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>