mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
Inline asm multiple alternative constraints development phase 2 - improved basic logic, added initial platform support.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117667 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3545635a60
commit
44ab89eb37
@ -52,7 +52,7 @@ GlobalVariable *ExtractTypeInfo(Value *V);
|
||||
|
||||
/// 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
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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);
|
||||
}
|
||||
|
||||
|
@ -1320,6 +1320,22 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -125,7 +125,7 @@ GlobalVariable *llvm::ExtractTypeInfo(Value *V) {
|
||||
/// 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];
|
||||
|
@ -5221,6 +5221,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
typedef SmallVector<SDISelAsmOperandInfo,16> SDISelAsmOperandInfoVector;
|
||||
|
||||
} // end llvm namespace.
|
||||
|
||||
/// isAllocatableRegister - If the specified register is safe to allocate,
|
||||
@ -5458,11 +5460,11 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
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.
|
||||
|
@ -2664,16 +2664,16 @@ unsigned TargetLowering::AsmOperandInfo::getMatchedOperand() const {
|
||||
/// 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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
// 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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
weightSum = -1; // Can't match.
|
||||
break;
|
||||
}
|
||||
Input.ConstraintVT = OpInfo.ConstraintVT;
|
||||
}
|
||||
}
|
||||
|
||||
weight = getMultipleConstraintMatchWeight(OpInfo, maIndex);
|
||||
if (weight == -1) {
|
||||
weightSum = -1;
|
||||
@ -2792,7 +2819,7 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
// 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 @@ std::vector<TargetLowering::AsmOperandInfo> TargetLowering::ParseConstraints(
|
||||
" with a matching output constraint of"
|
||||
" incompatible type!");
|
||||
}
|
||||
Input.ConstraintVT = OpInfo.ConstraintVT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -2828,22 +2855,23 @@ static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 @@ int TargetLowering::getMultipleConstraintMatchWeight(
|
||||
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;
|
||||
|
@ -5441,6 +5441,40 @@ ARMTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
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 {
|
||||
|
@ -241,6 +241,12 @@ namespace llvm {
|
||||
|
||||
|
||||
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;
|
||||
|
@ -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 @@ AlphaTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
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 {
|
||||
|
@ -87,6 +87,11 @@ namespace llvm {
|
||||
|
||||
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;
|
||||
|
@ -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 @@ BlackfinTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
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::
|
||||
|
@ -39,6 +39,12 @@ namespace llvm {
|
||||
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>
|
||||
|
@ -3193,7 +3193,7 @@ static std::string gccifyAsm(std::string asmstr) {
|
||||
// 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 @@ void CWriter::visitInlineAsm(CallInst &CI) {
|
||||
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 @@ void CWriter::visitInlineAsm(CallInst &CI) {
|
||||
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 @@ void CWriter::visitInlineAsm(CallInst &CI) {
|
||||
|
||||
// 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.
|
||||
|
@ -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 @@ SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const
|
||||
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
|
||||
|
@ -129,6 +129,11 @@ namespace llvm {
|
||||
|
||||
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;
|
||||
|
@ -908,6 +908,37 @@ getConstraintType(const std::string &Constraint) const
|
||||
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.
|
||||
|
@ -153,6 +153,11 @@ namespace llvm {
|
||||
// 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;
|
||||
|
@ -1269,6 +1269,37 @@ getConstraintType(const std::string &Constraint) const
|
||||
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.
|
||||
|
@ -139,6 +139,11 @@ namespace llvm {
|
||||
// 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;
|
||||
|
@ -2473,13 +2473,13 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
|
||||
// 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 @@ PPCTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
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 {
|
||||
|
@ -308,6 +308,12 @@ namespace llvm {
|
||||
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;
|
||||
|
@ -11428,7 +11428,7 @@ static bool LowerToBSwap(CallInst *CI) {
|
||||
|
||||
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::ConstraintType
|
||||
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 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
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;
|
||||
}
|
||||
|
@ -542,10 +542,9 @@ namespace llvm {
|
||||
|
||||
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>
|
||||
|
@ -743,7 +743,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
|
||||
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];
|
||||
|
@ -380,7 +380,7 @@ bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) {
|
||||
/// 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];
|
||||
|
||||
|
@ -76,11 +76,11 @@ InlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) :
|
||||
/// 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 @@ void InlineAsm::ConstraintInfo::selectAlternative(unsigned index) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ InlineAsm::ParseConstraints(StringRef Constraints) {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user