mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Move a bunch of inline asm code out of line.
llvm-svn: 50313
This commit is contained in:
parent
b5bd654163
commit
b83aaaa855
@ -1076,73 +1076,12 @@ public:
|
|||||||
ConstraintType(TargetLowering::C_Unknown),
|
ConstraintType(TargetLowering::C_Unknown),
|
||||||
CallOperandVal(0), ConstraintVT(MVT::Other) {
|
CallOperandVal(0), ConstraintVT(MVT::Other) {
|
||||||
}
|
}
|
||||||
|
};
|
||||||
/// getConstraintGenerality - Return an integer indicating how general CT is.
|
|
||||||
unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
|
|
||||||
switch (CT) {
|
|
||||||
default: assert(0 && "Unknown constraint type!");
|
|
||||||
case TargetLowering::C_Other:
|
|
||||||
case TargetLowering::C_Unknown:
|
|
||||||
return 0;
|
|
||||||
case TargetLowering::C_Register:
|
|
||||||
return 1;
|
|
||||||
case TargetLowering::C_RegisterClass:
|
|
||||||
return 2;
|
|
||||||
case TargetLowering::C_Memory:
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ComputeConstraintToUse - Determines the constraint code and constraint
|
/// ComputeConstraintToUse - Determines the constraint code and constraint
|
||||||
/// type to use.
|
/// type to use for the specific AsmOperandInfo, setting
|
||||||
void ComputeConstraintToUse(const TargetLowering &TLI) {
|
/// OpInfo.ConstraintCode and OpInfo.ConstraintType.
|
||||||
assert(!Codes.empty() && "Must have at least one constraint");
|
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo) const;
|
||||||
|
|
||||||
std::string *Current = &Codes[0];
|
|
||||||
TargetLowering::ConstraintType CurType = TLI.getConstraintType(*Current);
|
|
||||||
// Single-letter constraints ('r') are very common.
|
|
||||||
if (Codes.size() == 1) {
|
|
||||||
ConstraintCode = *Current;
|
|
||||||
ConstraintType = CurType;
|
|
||||||
} else {
|
|
||||||
unsigned CurGenerality = getConstraintGenerality(CurType);
|
|
||||||
|
|
||||||
// If we have multiple constraints, try to pick the most general one
|
|
||||||
// ahead of time. This isn't a wonderful solution, but handles common
|
|
||||||
// cases.
|
|
||||||
for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
|
|
||||||
TargetLowering::ConstraintType ThisType =
|
|
||||||
TLI.getConstraintType(Codes[j]);
|
|
||||||
unsigned ThisGenerality = getConstraintGenerality(ThisType);
|
|
||||||
if (ThisGenerality > CurGenerality) {
|
|
||||||
// This constraint letter is more general than the previous one,
|
|
||||||
// use it.
|
|
||||||
CurType = ThisType;
|
|
||||||
Current = &Codes[j];
|
|
||||||
CurGenerality = ThisGenerality;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstraintCode = *Current;
|
|
||||||
ConstraintType = CurType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'X' matches anything.
|
|
||||||
if (ConstraintCode == "X" && CallOperandVal) {
|
|
||||||
// Labels and constants are handled elsewhere ('X' is the only thing
|
|
||||||
// that matches labels).
|
|
||||||
if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Otherwise, try to resolve it to something we know about by looking at
|
|
||||||
// the actual operand type.
|
|
||||||
if (const char *Repl = TLI.LowerXConstraint(ConstraintVT)) {
|
|
||||||
ConstraintCode = Repl;
|
|
||||||
ConstraintType = TLI.getConstraintType(ConstraintCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// getConstraintType - Given a constraint, return the type of constraint it
|
/// getConstraintType - Given a constraint, return the type of constraint it
|
||||||
/// is for this target.
|
/// is for this target.
|
||||||
|
@ -3824,7 +3824,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
|
|||||||
OpInfo.ConstraintVT = OpVT;
|
OpInfo.ConstraintVT = OpVT;
|
||||||
|
|
||||||
// Compute the constraint code and ConstraintType to use.
|
// Compute the constraint code and ConstraintType to use.
|
||||||
OpInfo.ComputeConstraintToUse(TLI);
|
TLI.ComputeConstraintToUse(OpInfo);
|
||||||
|
|
||||||
// Keep track of whether we see an earlyclobber.
|
// Keep track of whether we see an earlyclobber.
|
||||||
SawEarlyClobber |= OpInfo.isEarlyClobber;
|
SawEarlyClobber |= OpInfo.isEarlyClobber;
|
||||||
|
@ -1498,6 +1498,7 @@ PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
|
|||||||
// Inline Assembler Implementation Methods
|
// Inline Assembler Implementation Methods
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
TargetLowering::ConstraintType
|
TargetLowering::ConstraintType
|
||||||
TargetLowering::getConstraintType(const std::string &Constraint) const {
|
TargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||||
// FIXME: lots more standard ones to handle.
|
// FIXME: lots more standard ones to handle.
|
||||||
@ -1646,6 +1647,102 @@ getRegForInlineAsmConstraint(const std::string &Constraint,
|
|||||||
return std::pair<unsigned, const TargetRegisterClass*>(0, 0);
|
return std::pair<unsigned, const TargetRegisterClass*>(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Constraint Selection.
|
||||||
|
|
||||||
|
/// getConstraintGenerality - Return an integer indicating how general CT
|
||||||
|
/// is.
|
||||||
|
static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
|
||||||
|
switch (CT) {
|
||||||
|
default: assert(0 && "Unknown constraint type!");
|
||||||
|
case TargetLowering::C_Other:
|
||||||
|
case TargetLowering::C_Unknown:
|
||||||
|
return 0;
|
||||||
|
case TargetLowering::C_Register:
|
||||||
|
return 1;
|
||||||
|
case TargetLowering::C_RegisterClass:
|
||||||
|
return 2;
|
||||||
|
case TargetLowering::C_Memory:
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ChooseConstraint - If there are multiple different constraints that we
|
||||||
|
/// could pick for this operand (e.g. "imr") try to pick the 'best' one.
|
||||||
|
/// This is somewhat tricky: constraints fall into three four classes:
|
||||||
|
/// Other -> immediates and magic values
|
||||||
|
/// Register -> one specific register
|
||||||
|
/// RegisterClass -> a group of regs
|
||||||
|
/// Memory -> memory
|
||||||
|
/// Ideally, we would pick the most specific constraint possible: if we have
|
||||||
|
/// something that fits into a register, we would pick it. The problem here
|
||||||
|
/// is that if we have something that could either be in a register or in
|
||||||
|
/// memory that use of the register could cause selection of *other*
|
||||||
|
/// operands to fail: they might only succeed if we pick memory. Because of
|
||||||
|
/// this the heuristic we use is:
|
||||||
|
///
|
||||||
|
/// 1) If there is an 'other' constraint, and if the operand is valid for
|
||||||
|
/// that constraint, use it. This makes us take advantage of 'i'
|
||||||
|
/// constraints when available.
|
||||||
|
/// 2) Otherwise, pick the most general constraint present. This prefers
|
||||||
|
/// 'm' over 'r', for example.
|
||||||
|
///
|
||||||
|
static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
|
||||||
|
const TargetLowering &TLI) {
|
||||||
|
assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
|
||||||
|
unsigned BestIdx = 0;
|
||||||
|
TargetLowering::ConstraintType BestType = TargetLowering::C_Unknown;
|
||||||
|
int BestGenerality = -1;
|
||||||
|
|
||||||
|
// Loop over the options, keeping track of the most general one.
|
||||||
|
for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) {
|
||||||
|
TargetLowering::ConstraintType CType =
|
||||||
|
TLI.getConstraintType(OpInfo.Codes[i]);
|
||||||
|
|
||||||
|
// This constraint letter is more general than the previous one, use it.
|
||||||
|
int Generality = getConstraintGenerality(CType);
|
||||||
|
if (Generality > BestGenerality) {
|
||||||
|
BestType = CType;
|
||||||
|
BestIdx = i;
|
||||||
|
BestGenerality = Generality;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpInfo.ConstraintCode = OpInfo.Codes[BestIdx];
|
||||||
|
OpInfo.ConstraintType = BestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ComputeConstraintToUse - Determines the constraint code and constraint
|
||||||
|
/// type to use for the specific AsmOperandInfo, setting
|
||||||
|
/// OpInfo.ConstraintCode and OpInfo.ConstraintType.
|
||||||
|
void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo) const {
|
||||||
|
assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
|
||||||
|
|
||||||
|
// Single-letter constraints ('r') are very common.
|
||||||
|
if (OpInfo.Codes.size() == 1) {
|
||||||
|
OpInfo.ConstraintCode = OpInfo.Codes[0];
|
||||||
|
OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode);
|
||||||
|
} else {
|
||||||
|
ChooseConstraint(OpInfo, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'X' matches anything.
|
||||||
|
if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
|
||||||
|
// Labels and constants are handled elsewhere ('X' is the only thing
|
||||||
|
// that matches labels).
|
||||||
|
if (isa<BasicBlock>(OpInfo.CallOperandVal) ||
|
||||||
|
isa<ConstantInt>(OpInfo.CallOperandVal))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Otherwise, try to resolve it to something we know about by looking at
|
||||||
|
// the actual operand type.
|
||||||
|
if (const char *Repl = LowerXConstraint(OpInfo.ConstraintVT)) {
|
||||||
|
OpInfo.ConstraintCode = Repl;
|
||||||
|
OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Loop Strength Reduction hooks
|
// Loop Strength Reduction hooks
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -962,7 +962,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the constraint code and ConstraintType to use.
|
// Compute the constraint code and ConstraintType to use.
|
||||||
OpInfo.ComputeConstraintToUse(*TLI);
|
TLI->ComputeConstraintToUse(OpInfo);
|
||||||
|
|
||||||
if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
|
if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
|
||||||
OpInfo.isIndirect) {
|
OpInfo.isIndirect) {
|
||||||
|
Loading…
Reference in New Issue
Block a user