[llvm-commits] [llvm] r117667 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/Blackfin/ lib/Target/CBackend/ lib/Target/CellSPU/ lib/Ta

Nick Lewycky nlewycky at google.com
Fri Oct 29 14:10:05 PDT 2010


On 29 October 2010 10:29, John Thompson
<John.Thompson.JTSoftware at gmail.com>wrote:

> Author: jtsoftware
> Date: Fri Oct 29 12:29:13 2010
> New Revision: 117667
>
> URL: http://llvm.org/viewvc/llvm-project?rev=117667&view=rev
> Log:
> Inline asm multiple alternative constraints development phase 2 - improved
> basic logic, added initial platform support.
>

This change makes SelectionDAGBuilder::visitInlineAsm use up 30k of stack
space, largely due to the switch from std::vector to SmallVector. Please
fix!

Nick

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


More information about the llvm-commits mailing list