mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Reverting back to original 1.8 version so I can manually merge in patch.
llvm-svn: 29584
This commit is contained in:
parent
f0b265b48b
commit
3707c6e4e3
@ -1829,20 +1829,7 @@ static void GenerateVariantsOf(TreePatternNode *N,
|
|||||||
// If this node is commutative, consider the commuted order.
|
// If this node is commutative, consider the commuted order.
|
||||||
if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) {
|
if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) {
|
||||||
assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
|
assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
|
||||||
// Don't count children which are actually register references.
|
|
||||||
unsigned NC = 0;
|
|
||||||
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
|
|
||||||
TreePatternNode *Child = N->getChild(i);
|
|
||||||
if (Child->isLeaf())
|
|
||||||
if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
|
|
||||||
Record *RR = DI->getDef();
|
|
||||||
if (RR->isSubClassOf("Register"))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
NC++;
|
|
||||||
}
|
|
||||||
// Consider the commuted order.
|
// Consider the commuted order.
|
||||||
if (NC == 2)
|
|
||||||
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
|
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
|
||||||
OutVariants, ISE);
|
OutVariants, ISE);
|
||||||
}
|
}
|
||||||
@ -2119,6 +2106,8 @@ private:
|
|||||||
// Names of all the folded nodes which produce chains.
|
// Names of all the folded nodes which produce chains.
|
||||||
std::vector<std::pair<std::string, unsigned> > FoldedChains;
|
std::vector<std::pair<std::string, unsigned> > FoldedChains;
|
||||||
std::set<std::string> Duplicates;
|
std::set<std::string> Duplicates;
|
||||||
|
/// These nodes are being marked "in-flight" so they cannot be folded.
|
||||||
|
std::vector<std::string> InflightNodes;
|
||||||
|
|
||||||
/// GeneratedCode - This is the buffer that we emit code to. The first bool
|
/// GeneratedCode - This is the buffer that we emit code to. The first bool
|
||||||
/// indicates whether this is an exit predicate (something that should be
|
/// indicates whether this is an exit predicate (something that should be
|
||||||
@ -2134,6 +2123,7 @@ private:
|
|||||||
std::vector<std::string> &TargetVTs;
|
std::vector<std::string> &TargetVTs;
|
||||||
|
|
||||||
std::string ChainName;
|
std::string ChainName;
|
||||||
|
bool DoReplace;
|
||||||
unsigned TmpNo;
|
unsigned TmpNo;
|
||||||
unsigned OpcNo;
|
unsigned OpcNo;
|
||||||
unsigned VTNo;
|
unsigned VTNo;
|
||||||
@ -2164,10 +2154,11 @@ public:
|
|||||||
std::vector<std::pair<bool, std::string> > &gc,
|
std::vector<std::pair<bool, std::string> > &gc,
|
||||||
std::set<std::pair<unsigned, std::string> > &gd,
|
std::set<std::pair<unsigned, std::string> > &gd,
|
||||||
std::vector<std::string> &to,
|
std::vector<std::string> &to,
|
||||||
std::vector<std::string> &tv)
|
std::vector<std::string> &tv,
|
||||||
|
bool dorep)
|
||||||
: ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
|
: ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
|
||||||
GeneratedCode(gc), GeneratedDecl(gd), TargetOpcodes(to), TargetVTs(tv),
|
GeneratedCode(gc), GeneratedDecl(gd), TargetOpcodes(to), TargetVTs(tv),
|
||||||
TmpNo(0), OpcNo(0), VTNo(0) {}
|
DoReplace(dorep), TmpNo(0), OpcNo(0), VTNo(0) {}
|
||||||
|
|
||||||
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
|
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
|
||||||
/// if the match fails. At this point, we already know that the opcode for N
|
/// if the match fails. At this point, we already know that the opcode for N
|
||||||
@ -2234,14 +2225,24 @@ public:
|
|||||||
bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
|
bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
|
||||||
bool HasOutFlag = PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE);
|
bool HasOutFlag = PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE);
|
||||||
bool EmittedUseCheck = false;
|
bool EmittedUseCheck = false;
|
||||||
|
bool EmittedSlctedCheck = false;
|
||||||
if (HasChain) {
|
if (HasChain) {
|
||||||
if (NodeHasChain)
|
if (NodeHasChain)
|
||||||
OpNo = 1;
|
OpNo = 1;
|
||||||
if (!isRoot) {
|
if (!isRoot) {
|
||||||
const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
|
const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
|
||||||
|
// Not in flight?
|
||||||
|
emitCheck("InFlightSet.count(" + RootName + ".Val) == 0");
|
||||||
// Multiple uses of actual result?
|
// Multiple uses of actual result?
|
||||||
emitCheck(RootName + ".hasOneUse()");
|
emitCheck(RootName + ".hasOneUse()");
|
||||||
EmittedUseCheck = true;
|
EmittedUseCheck = true;
|
||||||
|
// hasOneUse() check is not strong enough. If the original node has
|
||||||
|
// already been selected, it may have been replaced with another.
|
||||||
|
for (unsigned j = 0; j != CInfo.getNumResults(); j++)
|
||||||
|
emitCheck("!CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) +
|
||||||
|
"))");
|
||||||
|
|
||||||
|
EmittedSlctedCheck = true;
|
||||||
if (NodeHasChain) {
|
if (NodeHasChain) {
|
||||||
// FIXME: Don't fold if 1) the parent node writes a flag, 2) the node
|
// FIXME: Don't fold if 1) the parent node writes a flag, 2) the node
|
||||||
// has a chain use.
|
// has a chain use.
|
||||||
@ -2279,8 +2280,14 @@ public:
|
|||||||
PInfo.hasProperty(SDNodeInfo::SDNPHasChain) ||
|
PInfo.hasProperty(SDNodeInfo::SDNPHasChain) ||
|
||||||
PInfo.hasProperty(SDNodeInfo::SDNPInFlag) ||
|
PInfo.hasProperty(SDNodeInfo::SDNPInFlag) ||
|
||||||
PInfo.hasProperty(SDNodeInfo::SDNPOptInFlag))
|
PInfo.hasProperty(SDNodeInfo::SDNPOptInFlag))
|
||||||
emitCheck("CanBeFoldedBy(" + RootName + ".Val, " + ParentName +
|
if (PInfo.getNumOperands() > 1) {
|
||||||
|
emitCheck("!isNonImmUse(" + ParentName + ".Val, " + RootName +
|
||||||
".Val)");
|
".Val)");
|
||||||
|
} else {
|
||||||
|
emitCheck("(" + ParentName + ".getNumOperands() == 1 || !" +
|
||||||
|
"isNonImmUse(" + ParentName + ".Val, " + RootName +
|
||||||
|
".Val))");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2310,6 +2317,12 @@ public:
|
|||||||
// Multiple uses of actual result?
|
// Multiple uses of actual result?
|
||||||
emitCheck(RootName + ".hasOneUse()");
|
emitCheck(RootName + ".hasOneUse()");
|
||||||
}
|
}
|
||||||
|
if (!EmittedSlctedCheck)
|
||||||
|
// hasOneUse() check is not strong enough. If the original node has
|
||||||
|
// already been selected, it may have been replaced with another.
|
||||||
|
for (unsigned j = 0; j < CInfo.getNumResults(); j++)
|
||||||
|
emitCheck("!CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) +
|
||||||
|
"))");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
|
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
|
||||||
@ -2466,14 +2479,30 @@ public:
|
|||||||
for (unsigned i = 0; i < NumRes; ++i)
|
for (unsigned i = 0; i < NumRes; ++i)
|
||||||
emitDecl("CPTmp" + utostr(i+ResNo));
|
emitDecl("CPTmp" + utostr(i+ResNo));
|
||||||
|
|
||||||
std::string Code = Fn + "(" + Val;
|
std::string Code = "bool Match = " + Fn + "(" + Val;
|
||||||
for (unsigned i = 0; i < NumRes; i++)
|
for (unsigned i = 0; i < NumRes; i++)
|
||||||
Code += ", CPTmp" + utostr(i + ResNo);
|
Code += ", CPTmp" + utostr(i + ResNo);
|
||||||
emitCheck(Code + ")");
|
emitCode(Code + ");");
|
||||||
|
if (InflightNodes.size()) {
|
||||||
|
// Remove the in-flight nodes if the ComplexPattern does not match!
|
||||||
|
emitCode("if (!Match) {");
|
||||||
|
for (std::vector<std::string>::iterator AI = InflightNodes.begin(),
|
||||||
|
AE = InflightNodes.end(); AI != AE; ++AI)
|
||||||
|
emitCode(" SelectionDAG::RemoveInFlightSetEntry(InFlightSet, " +
|
||||||
|
*AI + ".Val);");
|
||||||
|
emitCode("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
emitCheck("Match");
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NumRes; ++i) {
|
||||||
|
emitCode("SelectionDAG::InsertInFlightSetEntry(InFlightSet, CPTmp" +
|
||||||
|
utostr(i+ResNo) + ".Val);");
|
||||||
|
InflightNodes.push_back("CPTmp" + utostr(i+ResNo));
|
||||||
|
}
|
||||||
for (unsigned i = 0; i < NumRes; ++i) {
|
for (unsigned i = 0; i < NumRes; ++i) {
|
||||||
emitDecl("Tmp" + utostr(i+ResNo));
|
emitDecl("Tmp" + utostr(i+ResNo));
|
||||||
emitCode("AddToQueue(Tmp" + utostr(i+ResNo) + ", CPTmp" +
|
emitCode("Select(Tmp" + utostr(i+ResNo) + ", CPTmp" +
|
||||||
utostr(i+ResNo) + ");");
|
utostr(i+ResNo) + ");");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2485,14 +2514,14 @@ public:
|
|||||||
if (LikeLeaf)
|
if (LikeLeaf)
|
||||||
emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
|
emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
|
||||||
else {
|
else {
|
||||||
emitCode("AddToQueue(Tmp" + utostr(ResNo) + ", " + Val + ");");
|
emitCode("Select(Tmp" + utostr(ResNo) + ", " + Val + ");");
|
||||||
|
}
|
||||||
|
|
||||||
if (isRoot && N->isLeaf()) {
|
if (isRoot && N->isLeaf()) {
|
||||||
emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
|
|
||||||
emitCode("Result = Tmp" + utostr(ResNo) + ";");
|
emitCode("Result = Tmp" + utostr(ResNo) + ";");
|
||||||
emitCode("return;");
|
emitCode("return;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
|
// Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
|
||||||
// value if used multiple times by this pattern result.
|
// value if used multiple times by this pattern result.
|
||||||
Val = "Tmp"+utostr(ResNo);
|
Val = "Tmp"+utostr(ResNo);
|
||||||
@ -2585,6 +2614,22 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure these operands which would be selected won't be folded while
|
||||||
|
// the isel traverses the DAG upward.
|
||||||
|
for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
|
||||||
|
TreePatternNode *Child = EmitOrder[i].second;
|
||||||
|
if (!Child->getName().empty()) {
|
||||||
|
std::string &Val = VariableMap[Child->getName()];
|
||||||
|
assert(!Val.empty() &&
|
||||||
|
"Variable referenced but not defined and not caught earlier!");
|
||||||
|
if (Child->isLeaf() && !NodeGetComplexPattern(Child, ISE)) {
|
||||||
|
emitCode("SelectionDAG::InsertInFlightSetEntry(InFlightSet, " +
|
||||||
|
Val + ".Val);");
|
||||||
|
InflightNodes.push_back(Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Emit all of the operands.
|
// Emit all of the operands.
|
||||||
std::vector<std::pair<unsigned, unsigned> > NumTemps(EmitOrder.size());
|
std::vector<std::pair<unsigned, unsigned> > NumTemps(EmitOrder.size());
|
||||||
for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
|
for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
|
||||||
@ -2604,12 +2649,20 @@ public:
|
|||||||
// Emit all the chain and CopyToReg stuff.
|
// Emit all the chain and CopyToReg stuff.
|
||||||
bool ChainEmitted = NodeHasChain;
|
bool ChainEmitted = NodeHasChain;
|
||||||
if (NodeHasChain)
|
if (NodeHasChain)
|
||||||
emitCode("AddToQueue(" + ChainName + ", " + ChainName + ");");
|
emitCode("Select(" + ChainName + ", " + ChainName + ");");
|
||||||
if (NodeHasInFlag || HasImpInputs)
|
if (NodeHasInFlag || HasImpInputs)
|
||||||
EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
|
EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
|
||||||
if (NodeHasOptInFlag) {
|
if (NodeHasOptInFlag) {
|
||||||
emitCode("if (HasInFlag)");
|
emitCode("if (HasInFlag)");
|
||||||
emitCode(" AddToQueue(InFlag, N.getOperand(N.getNumOperands()-1));");
|
emitCode(" Select(InFlag, N.getOperand(N.getNumOperands()-1));");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRoot) {
|
||||||
|
// The operands have been selected. Remove them from InFlightSet.
|
||||||
|
for (std::vector<std::string>::iterator AI = InflightNodes.begin(),
|
||||||
|
AE = InflightNodes.end(); AI != AE; ++AI)
|
||||||
|
emitCode("SelectionDAG::RemoveInFlightSetEntry(InFlightSet, " +
|
||||||
|
*AI + ".Val);");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NumResults = Inst.getNumResults();
|
unsigned NumResults = Inst.getNumResults();
|
||||||
@ -2661,7 +2714,7 @@ public:
|
|||||||
emitCode("for (unsigned i = 2, e = N.getNumOperands(); "
|
emitCode("for (unsigned i = 2, e = N.getNumOperands(); "
|
||||||
"i != e; ++i) {");
|
"i != e; ++i) {");
|
||||||
emitCode(" SDOperand VarOp(0, 0);");
|
emitCode(" SDOperand VarOp(0, 0);");
|
||||||
emitCode(" AddToQueue(VarOp, N.getOperand(i));");
|
emitCode(" Select(VarOp, N.getOperand(i));");
|
||||||
emitCode(" Ops.push_back(VarOp);");
|
emitCode(" Ops.push_back(VarOp);");
|
||||||
emitCode("}");
|
emitCode("}");
|
||||||
}
|
}
|
||||||
@ -2683,7 +2736,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (HasVarOps)
|
if (HasVarOps)
|
||||||
Code += ", &Ops[0], Ops.size()";
|
Code += ", Ops";
|
||||||
else if (NodeHasOptInFlag)
|
else if (NodeHasOptInFlag)
|
||||||
Code = "HasInFlag ? " + Code + ", InFlag) : " + Code;
|
Code = "HasInFlag ? " + Code + ", InFlag) : " + Code;
|
||||||
|
|
||||||
@ -2704,35 +2757,50 @@ public:
|
|||||||
return std::make_pair(1, ResNo);
|
return std::make_pair(1, ResNo);
|
||||||
|
|
||||||
for (unsigned i = 0; i < NumResults; i++)
|
for (unsigned i = 0; i < NumResults; i++)
|
||||||
emitCode("ReplaceUses(SDOperand(N.Val, " +
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
|
||||||
utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
|
utostr(i) + ", ResNode, " + utostr(i) + ");");
|
||||||
|
|
||||||
if (NodeHasOutFlag)
|
if (NodeHasOutFlag)
|
||||||
emitCode("InFlag = SDOperand(ResNode, " +
|
emitCode("InFlag = SDOperand(ResNode, " +
|
||||||
utostr(NumResults + (unsigned)NodeHasChain) + ");");
|
utostr(NumResults + (unsigned)NodeHasChain) + ");");
|
||||||
|
|
||||||
if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) {
|
if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) {
|
||||||
emitCode("ReplaceUses(SDOperand(N.Val, 0), SDOperand(ResNode, 0));");
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, "
|
||||||
|
"0, ResNode, 0);");
|
||||||
NumResults = 1;
|
NumResults = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InputHasChain)
|
if (InputHasChain) {
|
||||||
emitCode("ReplaceUses(SDOperand(N.Val, " +
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
|
||||||
utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " +
|
utostr(PatResults) + ", " + ChainName + ".Val, " +
|
||||||
ChainName + ".ResNo" + "));");
|
ChainName + ".ResNo" + ");");
|
||||||
|
if (DoReplace)
|
||||||
|
emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " +
|
||||||
|
utostr(PatResults) + ", " + ChainName + ".Val, " +
|
||||||
|
ChainName + ".ResNo" + ");");
|
||||||
|
}
|
||||||
|
|
||||||
if (FoldedChains.size() > 0) {
|
if (FoldedChains.size() > 0) {
|
||||||
std::string Code;
|
std::string Code;
|
||||||
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
|
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
|
||||||
emitCode("ReplaceUses(SDOperand(" +
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, " +
|
||||||
FoldedChains[j].first + ".Val, " +
|
FoldedChains[j].first + ".Val, " +
|
||||||
utostr(FoldedChains[j].second) + "), SDOperand(ResNode, " +
|
utostr(FoldedChains[j].second) + ", ResNode, " +
|
||||||
utostr(NumResults) + "));");
|
utostr(NumResults) + ");");
|
||||||
|
|
||||||
|
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) {
|
||||||
|
std::string Code =
|
||||||
|
FoldedChains[j].first + ".Val, " +
|
||||||
|
utostr(FoldedChains[j].second) + ", ";
|
||||||
|
emitCode("AddHandleReplacement(" + Code + "ResNode, " +
|
||||||
|
utostr(NumResults) + ");");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NodeHasOutFlag)
|
if (NodeHasOutFlag)
|
||||||
emitCode("ReplaceUses(SDOperand(N.Val, " +
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
|
||||||
utostr(PatResults + (unsigned)InputHasChain) +"), InFlag);");
|
utostr(PatResults + (unsigned)InputHasChain) +
|
||||||
|
", InFlag.Val, InFlag.ResNo);");
|
||||||
|
|
||||||
// User does not expect the instruction would produce a chain!
|
// User does not expect the instruction would produce a chain!
|
||||||
bool AddedChain = NodeHasChain && !InputHasChain;
|
bool AddedChain = NodeHasChain && !InputHasChain;
|
||||||
@ -2789,7 +2857,8 @@ public:
|
|||||||
if (NodeHasInFlag || HasImpInputs)
|
if (NodeHasInFlag || HasImpInputs)
|
||||||
Code += ", InFlag";
|
Code += ", InFlag";
|
||||||
emitCode(Code + ");");
|
emitCode(Code + ");");
|
||||||
emitCode(" ReplaceUses(N, SDOperand(ResNode, 0));");
|
emitCode(" SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo"
|
||||||
|
", ResNode, 0);");
|
||||||
emitCode(" Result = SDOperand(ResNode, 0);");
|
emitCode(" Result = SDOperand(ResNode, 0);");
|
||||||
emitCode("}");
|
emitCode("}");
|
||||||
}
|
}
|
||||||
@ -2807,7 +2876,9 @@ public:
|
|||||||
emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
|
emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
|
||||||
+ "(Tmp" + utostr(OpVal) + ".Val);");
|
+ "(Tmp" + utostr(OpVal) + ".Val);");
|
||||||
if (isRoot) {
|
if (isRoot) {
|
||||||
emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
|
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val,"
|
||||||
|
"N.ResNo, Tmp" + utostr(ResNo) + ".Val, Tmp" +
|
||||||
|
utostr(ResNo) + ".ResNo);");
|
||||||
emitCode("Result = Tmp" + utostr(ResNo) + ";");
|
emitCode("Result = Tmp" + utostr(ResNo) + ";");
|
||||||
emitCode("return;");
|
emitCode("return;");
|
||||||
}
|
}
|
||||||
@ -2824,13 +2895,11 @@ public:
|
|||||||
/// 'Pat' may be missing types. If we find an unresolved type to add a check
|
/// 'Pat' may be missing types. If we find an unresolved type to add a check
|
||||||
/// for, this returns true otherwise false if Pat has all types.
|
/// for, this returns true otherwise false if Pat has all types.
|
||||||
bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
|
bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
|
||||||
const std::string &Prefix, bool isRoot = false) {
|
const std::string &Prefix) {
|
||||||
// Did we find one?
|
// Did we find one?
|
||||||
if (Pat->getExtTypes() != Other->getExtTypes()) {
|
if (Pat->getExtTypes() != Other->getExtTypes()) {
|
||||||
// Move a type over from 'other' to 'pat'.
|
// Move a type over from 'other' to 'pat'.
|
||||||
Pat->setTypes(Other->getExtTypes());
|
Pat->setTypes(Other->getExtTypes());
|
||||||
// The top level node type is checked outside of the select function.
|
|
||||||
if (!isRoot)
|
|
||||||
emitCheck(Prefix + ".Val->getValueType(0) == " +
|
emitCheck(Prefix + ".Val->getValueType(0) == " +
|
||||||
getName(Pat->getTypeNum(0)));
|
getName(Pat->getTypeNum(0)));
|
||||||
return true;
|
return true;
|
||||||
@ -2871,7 +2940,7 @@ private:
|
|||||||
if (RR->isSubClassOf("Register")) {
|
if (RR->isSubClassOf("Register")) {
|
||||||
MVT::ValueType RVT = getRegisterValueType(RR, T);
|
MVT::ValueType RVT = getRegisterValueType(RR, T);
|
||||||
if (RVT == MVT::Flag) {
|
if (RVT == MVT::Flag) {
|
||||||
emitCode("AddToQueue(InFlag, " + RootName + utostr(OpNo) + ");");
|
emitCode("Select(InFlag, " + RootName + utostr(OpNo) + ");");
|
||||||
} else {
|
} else {
|
||||||
if (!ChainEmitted) {
|
if (!ChainEmitted) {
|
||||||
emitDecl("Chain");
|
emitDecl("Chain");
|
||||||
@ -2879,7 +2948,7 @@ private:
|
|||||||
ChainName = "Chain";
|
ChainName = "Chain";
|
||||||
ChainEmitted = true;
|
ChainEmitted = true;
|
||||||
}
|
}
|
||||||
emitCode("AddToQueue(" + RootName + utostr(OpNo) + ", " +
|
emitCode("Select(" + RootName + utostr(OpNo) + ", " +
|
||||||
RootName + utostr(OpNo) + ");");
|
RootName + utostr(OpNo) + ");");
|
||||||
emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName +
|
emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName +
|
||||||
", CurDAG->getRegister(" + ISE.getQualifiedName(RR) +
|
", CurDAG->getRegister(" + ISE.getQualifiedName(RR) +
|
||||||
@ -2894,7 +2963,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (HasInFlag)
|
if (HasInFlag)
|
||||||
emitCode("AddToQueue(InFlag, " + RootName +
|
emitCode("Select(InFlag, " + RootName +
|
||||||
".getOperand(" + utostr(OpNo) + "));");
|
".getOperand(" + utostr(OpNo) + "));");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2940,11 +3009,13 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
|
|||||||
std::vector<std::pair<bool, std::string> > &GeneratedCode,
|
std::vector<std::pair<bool, std::string> > &GeneratedCode,
|
||||||
std::set<std::pair<unsigned, std::string> > &GeneratedDecl,
|
std::set<std::pair<unsigned, std::string> > &GeneratedDecl,
|
||||||
std::vector<std::string> &TargetOpcodes,
|
std::vector<std::string> &TargetOpcodes,
|
||||||
std::vector<std::string> &TargetVTs) {
|
std::vector<std::string> &TargetVTs,
|
||||||
|
bool DoReplace) {
|
||||||
PatternCodeEmitter Emitter(*this, Pattern.getPredicates(),
|
PatternCodeEmitter Emitter(*this, Pattern.getPredicates(),
|
||||||
Pattern.getSrcPattern(), Pattern.getDstPattern(),
|
Pattern.getSrcPattern(), Pattern.getDstPattern(),
|
||||||
GeneratedCode, GeneratedDecl,
|
GeneratedCode, GeneratedDecl,
|
||||||
TargetOpcodes, TargetVTs);
|
TargetOpcodes, TargetVTs,
|
||||||
|
DoReplace);
|
||||||
|
|
||||||
// Emit the matcher, capturing named arguments in VariableMap.
|
// Emit the matcher, capturing named arguments in VariableMap.
|
||||||
bool FoundChain = false;
|
bool FoundChain = false;
|
||||||
@ -2984,7 +3055,7 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
|
|||||||
// Insert a check for an unresolved type and add it to the tree. If we find
|
// Insert a check for an unresolved type and add it to the tree. If we find
|
||||||
// an unresolved type to add a check for, this returns true and we iterate,
|
// an unresolved type to add a check for, this returns true and we iterate,
|
||||||
// otherwise we are done.
|
// otherwise we are done.
|
||||||
} while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
|
} while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N"));
|
||||||
|
|
||||||
Emitter.EmitResultCode(Pattern.getDstPattern(), false, true /*the root*/);
|
Emitter.EmitResultCode(Pattern.getDstPattern(), false, true /*the root*/);
|
||||||
delete Pat;
|
delete Pat;
|
||||||
@ -3071,9 +3142,7 @@ void DAGISelEmitter::EmitPatterns(std::vector<std::pair<PatternToMatch*,
|
|||||||
OS << std::string(Indent, ' ') << "// Pattern complexity = "
|
OS << std::string(Indent, ' ') << "// Pattern complexity = "
|
||||||
<< getPatternSize(Pattern.getSrcPattern(), *this) + AddedComplexity
|
<< getPatternSize(Pattern.getSrcPattern(), *this) + AddedComplexity
|
||||||
<< " cost = "
|
<< " cost = "
|
||||||
<< getResultPatternCost(Pattern.getDstPattern(), *this)
|
<< getResultPatternCost(Pattern.getDstPattern(), *this) << "\n";
|
||||||
<< " size = "
|
|
||||||
<< getResultPatternSize(Pattern.getDstPattern(), *this) << "\n";
|
|
||||||
}
|
}
|
||||||
EmitPatterns(Other, Indent, OS);
|
EmitPatterns(Other, Indent, OS);
|
||||||
return;
|
return;
|
||||||
@ -3172,11 +3241,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each opcode, there might be multiple select functions, one per
|
|
||||||
// ValueType of the node (or its first operand if it doesn't produce a
|
|
||||||
// non-chain result.
|
|
||||||
std::map<std::string, std::vector<std::string> > OpcodeVTMap;
|
|
||||||
|
|
||||||
// Emit one Select_* method for each top-level opcode. We do this instead of
|
// Emit one Select_* method for each top-level opcode. We do this instead of
|
||||||
// emitting one giant switch statement to support compilers where this will
|
// emitting one giant switch statement to support compilers where this will
|
||||||
// result in the recursive functions taking less stack space.
|
// result in the recursive functions taking less stack space.
|
||||||
@ -3185,39 +3249,18 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
||||||
const std::string &OpName = PBOI->first->getName();
|
const std::string &OpName = PBOI->first->getName();
|
||||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
||||||
std::vector<PatternToMatch*> &PatternsOfOp = PBOI->second;
|
bool OptSlctOrder =
|
||||||
assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
|
(OpcodeInfo.hasProperty(SDNodeInfo::SDNPHasChain) &&
|
||||||
|
OpcodeInfo.getNumResults() > 0);
|
||||||
|
std::vector<PatternToMatch*> &Patterns = PBOI->second;
|
||||||
|
assert(!Patterns.empty() && "No patterns but map has entry?");
|
||||||
|
|
||||||
// We want to emit all of the matching code now. However, we want to emit
|
// We want to emit all of the matching code now. However, we want to emit
|
||||||
// the matches in order of minimal cost. Sort the patterns so the least
|
// the matches in order of minimal cost. Sort the patterns so the least
|
||||||
// cost one is at the start.
|
// cost one is at the start.
|
||||||
std::stable_sort(PatternsOfOp.begin(), PatternsOfOp.end(),
|
std::stable_sort(Patterns.begin(), Patterns.end(),
|
||||||
PatternSortingPredicate(*this));
|
PatternSortingPredicate(*this));
|
||||||
|
|
||||||
// Split them into groups by type.
|
|
||||||
std::map<MVT::ValueType, std::vector<PatternToMatch*> > PatternsByType;
|
|
||||||
for (unsigned i = 0, e = PatternsOfOp.size(); i != e; ++i) {
|
|
||||||
PatternToMatch *Pat = PatternsOfOp[i];
|
|
||||||
TreePatternNode *SrcPat = Pat->getSrcPattern();
|
|
||||||
if (OpcodeInfo.getNumResults() == 0 && SrcPat->getNumChildren() > 0)
|
|
||||||
SrcPat = SrcPat->getChild(0);
|
|
||||||
MVT::ValueType VT = SrcPat->getTypeNum(0);
|
|
||||||
std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator TI =
|
|
||||||
PatternsByType.find(VT);
|
|
||||||
if (TI != PatternsByType.end())
|
|
||||||
TI->second.push_back(Pat);
|
|
||||||
else {
|
|
||||||
std::vector<PatternToMatch*> PVec;
|
|
||||||
PVec.push_back(Pat);
|
|
||||||
PatternsByType.insert(std::make_pair(VT, PVec));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator
|
|
||||||
II = PatternsByType.begin(), EE = PatternsByType.end(); II != EE;
|
|
||||||
++II) {
|
|
||||||
MVT::ValueType OpVT = II->first;
|
|
||||||
std::vector<PatternToMatch*> &Patterns = II->second;
|
|
||||||
typedef std::vector<std::pair<bool, std::string> > CodeList;
|
typedef std::vector<std::pair<bool, std::string> > CodeList;
|
||||||
typedef std::vector<std::pair<bool, std::string> >::iterator CodeListI;
|
typedef std::vector<std::pair<bool, std::string> >::iterator CodeListI;
|
||||||
|
|
||||||
@ -3232,7 +3275,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
std::vector<std::string> TargetOpcodes;
|
std::vector<std::string> TargetOpcodes;
|
||||||
std::vector<std::string> TargetVTs;
|
std::vector<std::string> TargetVTs;
|
||||||
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
|
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
|
||||||
TargetOpcodes, TargetVTs);
|
TargetOpcodes, TargetVTs, OptSlctOrder);
|
||||||
for (std::set<std::pair<unsigned, std::string> >::iterator
|
for (std::set<std::pair<unsigned, std::string> >::iterator
|
||||||
si = GeneratedDecl.begin(), se = GeneratedDecl.end(); si!=se; ++si)
|
si = GeneratedDecl.begin(), se = GeneratedDecl.end(); si!=se; ++si)
|
||||||
AllGenDecls.insert(*si);
|
AllGenDecls.insert(*si);
|
||||||
@ -3260,7 +3303,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
// patterns after it CANNOT ever match. Error out.
|
// patterns after it CANNOT ever match. Error out.
|
||||||
if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
|
if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
|
||||||
std::cerr << "Pattern '";
|
std::cerr << "Pattern '";
|
||||||
CodeForPatterns[i+1].first->getSrcPattern()->print(std::cerr);
|
CodeForPatterns[i+1].first->getSrcPattern()->print(OS);
|
||||||
std::cerr << "' is impossible to select!\n";
|
std::cerr << "' is impossible to select!\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -3284,7 +3327,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string CalleeDecls;
|
std::string CalleeDecls;
|
||||||
std::string CalleeCode = "(SDOperand &Result, const SDOperand &N";
|
std::string CalleeCode = "(SDOperand &Result, SDOperand &N";
|
||||||
std::string CallerCode = "(Result, N";
|
std::string CallerCode = "(Result, N";
|
||||||
for (unsigned j = 0, e = TargetOpcodes.size(); j != e; ++j) {
|
for (unsigned j = 0, e = TargetOpcodes.size(); j != e; ++j) {
|
||||||
CalleeCode += ", unsigned Opc" + utostr(j);
|
CalleeCode += ", unsigned Opc" + utostr(j);
|
||||||
@ -3350,19 +3393,20 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print function.
|
// Print function.
|
||||||
std::string OpVTStr = (OpVT != MVT::isVoid && OpVT != MVT::iPTR)
|
OS << "void Select_" << OpName << "(SDOperand &Result, SDOperand N) {\n";
|
||||||
? getEnumName(OpVT).substr(5) : "" ;
|
if (OptSlctOrder) {
|
||||||
std::map<std::string, std::vector<std::string> >::iterator OpVTI =
|
OS << " if (N.ResNo == " << OpcodeInfo.getNumResults()
|
||||||
OpcodeVTMap.find(OpName);
|
<< " && N.getValue(0).hasOneUse()) {\n"
|
||||||
if (OpVTI == OpcodeVTMap.end()) {
|
<< " SDOperand Dummy = "
|
||||||
std::vector<std::string> VTSet;
|
<< "CurDAG->getNode(ISD::HANDLENODE, MVT::Other, N);\n"
|
||||||
VTSet.push_back(OpVTStr);
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, "
|
||||||
OpcodeVTMap.insert(std::make_pair(OpName, VTSet));
|
<< OpcodeInfo.getNumResults() << ", Dummy.Val, 0);\n"
|
||||||
} else
|
<< " SelectionDAG::InsertISelMapEntry(HandleMap, N.Val, "
|
||||||
OpVTI->second.push_back(OpVTStr);
|
<< OpcodeInfo.getNumResults() << ", Dummy.Val, 0);\n"
|
||||||
|
<< " Result = Dummy;\n"
|
||||||
OS << "void Select_" << OpName << (OpVTStr != "" ? "_" : "")
|
<< " return;\n"
|
||||||
<< OpVTStr << "(SDOperand &Result, const SDOperand &N) {\n";
|
<< " }\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Print all declarations.
|
// Print all declarations.
|
||||||
for (std::set<std::pair<unsigned, std::string> >::iterator
|
for (std::set<std::pair<unsigned, std::string> >::iterator
|
||||||
@ -3407,23 +3451,21 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
OS << "}\n\n";
|
OS << "}\n\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Emit boilerplate.
|
// Emit boilerplate.
|
||||||
OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
|
OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
|
||||||
<< " std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end());\n"
|
<< " std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end());\n"
|
||||||
<< " AddToQueue(Ops[0], N.getOperand(0)); // Select the chain.\n\n"
|
<< " Select(Ops[0], N.getOperand(0)); // Select the chain.\n\n"
|
||||||
<< " // Select the flag operand.\n"
|
<< " // Select the flag operand.\n"
|
||||||
<< " if (Ops.back().getValueType() == MVT::Flag)\n"
|
<< " if (Ops.back().getValueType() == MVT::Flag)\n"
|
||||||
<< " AddToQueue(Ops.back(), Ops.back());\n"
|
<< " Select(Ops.back(), Ops.back());\n"
|
||||||
<< " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n"
|
<< " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n"
|
||||||
<< " std::vector<MVT::ValueType> VTs;\n"
|
<< " std::vector<MVT::ValueType> VTs;\n"
|
||||||
<< " VTs.push_back(MVT::Other);\n"
|
<< " VTs.push_back(MVT::Other);\n"
|
||||||
<< " VTs.push_back(MVT::Flag);\n"
|
<< " VTs.push_back(MVT::Flag);\n"
|
||||||
<< " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, &Ops[0], "
|
<< " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, Ops);\n"
|
||||||
"Ops.size());\n"
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, New.Val, 0);\n"
|
||||||
<< " ReplaceUses(SDOperand(N.Val, 0), New);\n"
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, New.Val, 1);\n"
|
||||||
<< " ReplaceUses(SDOperand(N.Val, 1), SDOperand(New.Val, 1));\n"
|
|
||||||
<< " Result = New.getValue(N.ResNo);\n"
|
<< " Result = New.getValue(N.ResNo);\n"
|
||||||
<< " return;\n"
|
<< " return;\n"
|
||||||
<< "}\n\n";
|
<< "}\n\n";
|
||||||
@ -3436,6 +3478,11 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
<< " Result = N;\n"
|
<< " Result = N;\n"
|
||||||
<< " return; // Already selected.\n"
|
<< " return; // Already selected.\n"
|
||||||
<< " }\n\n"
|
<< " }\n\n"
|
||||||
|
<< " std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N);\n"
|
||||||
|
<< " if (CGMI != CodeGenMap.end()) {\n"
|
||||||
|
<< " Result = CGMI->second;\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " }\n\n"
|
||||||
<< " switch (N.getOpcode()) {\n"
|
<< " switch (N.getOpcode()) {\n"
|
||||||
<< " default: break;\n"
|
<< " default: break;\n"
|
||||||
<< " case ISD::EntryToken: // These leaves remain the same.\n"
|
<< " case ISD::EntryToken: // These leaves remain the same.\n"
|
||||||
@ -3452,18 +3499,96 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
<< " }\n"
|
<< " }\n"
|
||||||
<< " case ISD::AssertSext:\n"
|
<< " case ISD::AssertSext:\n"
|
||||||
<< " case ISD::AssertZext: {\n"
|
<< " case ISD::AssertZext: {\n"
|
||||||
<< " AddToQueue(Result, N.getOperand(0));\n"
|
<< " SDOperand Tmp0;\n"
|
||||||
<< " ReplaceUses(N, Result);\n"
|
<< " Select(Tmp0, N.getOperand(0));\n"
|
||||||
|
<< " if (!N.Val->hasOneUse())\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, "
|
||||||
|
<< "Tmp0.Val, Tmp0.ResNo);\n"
|
||||||
|
<< " Result = Tmp0;\n"
|
||||||
<< " return;\n"
|
<< " return;\n"
|
||||||
<< " }\n"
|
<< " }\n"
|
||||||
<< " case ISD::TokenFactor:\n"
|
<< " case ISD::TokenFactor:\n"
|
||||||
<< " case ISD::CopyFromReg:\n"
|
<< " if (N.getNumOperands() == 2) {\n"
|
||||||
<< " case ISD::CopyToReg: {\n"
|
<< " SDOperand Op0, Op1;\n"
|
||||||
|
<< " Select(Op0, N.getOperand(0));\n"
|
||||||
|
<< " Select(Op1, N.getOperand(1));\n"
|
||||||
|
<< " Result = \n"
|
||||||
|
<< " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, "
|
||||||
|
<< "Result.Val, Result.ResNo);\n"
|
||||||
|
<< " } else {\n"
|
||||||
|
<< " std::vector<SDOperand> Ops;\n"
|
||||||
<< " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n"
|
<< " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n"
|
||||||
<< " SDOperand Dummy;\n"
|
<< " SDOperand Val;\n"
|
||||||
<< " AddToQueue(Dummy, N.getOperand(i));\n"
|
<< " Select(Val, N.getOperand(i));\n"
|
||||||
|
<< " Ops.push_back(Val);\n"
|
||||||
<< " }\n"
|
<< " }\n"
|
||||||
|
<< " Result = \n"
|
||||||
|
<< " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, "
|
||||||
|
<< "Result.Val, Result.ResNo);\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " case ISD::CopyFromReg: {\n"
|
||||||
|
<< " SDOperand Chain;\n"
|
||||||
|
<< " Select(Chain, N.getOperand(0));\n"
|
||||||
|
<< " unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();\n"
|
||||||
|
<< " MVT::ValueType VT = N.Val->getValueType(0);\n"
|
||||||
|
<< " if (N.Val->getNumValues() == 2) {\n"
|
||||||
|
<< " if (Chain == N.getOperand(0)) {\n"
|
||||||
|
<< " Result = N; // No change\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, "
|
||||||
|
<< "New.Val, 0);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, "
|
||||||
|
<< "New.Val, 1);\n"
|
||||||
|
<< " Result = New.getValue(N.ResNo);\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " } else {\n"
|
||||||
|
<< " SDOperand Flag;\n"
|
||||||
|
<< " if (N.getNumOperands() == 3) Select(Flag, N.getOperand(2));\n"
|
||||||
|
<< " if (Chain == N.getOperand(0) &&\n"
|
||||||
|
<< " (N.getNumOperands() == 2 || Flag == N.getOperand(2))) {\n"
|
||||||
|
<< " Result = N; // No change\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT, Flag);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, "
|
||||||
|
<< "New.Val, 0);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, "
|
||||||
|
<< "New.Val, 1);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 2, "
|
||||||
|
<< "New.Val, 2);\n"
|
||||||
|
<< " Result = New.getValue(N.ResNo);\n"
|
||||||
|
<< " return;\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " case ISD::CopyToReg: {\n"
|
||||||
|
<< " SDOperand Chain;\n"
|
||||||
|
<< " Select(Chain, N.getOperand(0));\n"
|
||||||
|
<< " unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();\n"
|
||||||
|
<< " SDOperand Val;\n"
|
||||||
|
<< " Select(Val, N.getOperand(2));\n"
|
||||||
<< " Result = N;\n"
|
<< " Result = N;\n"
|
||||||
|
<< " if (N.Val->getNumValues() == 1) {\n"
|
||||||
|
<< " if (Chain != N.getOperand(0) || Val != N.getOperand(2))\n"
|
||||||
|
<< " Result = CurDAG->getCopyToReg(Chain, Reg, Val);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, "
|
||||||
|
<< "Result.Val, 0);\n"
|
||||||
|
<< " } else {\n"
|
||||||
|
<< " SDOperand Flag(0, 0);\n"
|
||||||
|
<< " if (N.getNumOperands() == 4) Select(Flag, N.getOperand(3));\n"
|
||||||
|
<< " if (Chain != N.getOperand(0) || Val != N.getOperand(2) ||\n"
|
||||||
|
<< " (N.getNumOperands() == 4 && Flag != N.getOperand(3)))\n"
|
||||||
|
<< " Result = CurDAG->getCopyToReg(Chain, Reg, Val, Flag);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, "
|
||||||
|
<< "Result.Val, 0);\n"
|
||||||
|
<< " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, "
|
||||||
|
<< "Result.Val, 1);\n"
|
||||||
|
<< " Result = Result.getValue(N.ResNo);\n"
|
||||||
|
<< " }\n"
|
||||||
<< " return;\n"
|
<< " return;\n"
|
||||||
<< " }\n"
|
<< " }\n"
|
||||||
<< " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n";
|
<< " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n";
|
||||||
@ -3475,48 +3600,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
||||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
||||||
const std::string &OpName = PBOI->first->getName();
|
OS << " case " << OpcodeInfo.getEnumName() << ": "
|
||||||
// Potentially multiple versions of select for this opcode. One for each
|
<< std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ')
|
||||||
// ValueType of the node (or its first true operand if it doesn't produce a
|
<< "Select_" << PBOI->first->getName() << "(Result, N); return;\n";
|
||||||
// result.
|
|
||||||
std::map<std::string, std::vector<std::string> >::iterator OpVTI =
|
|
||||||
OpcodeVTMap.find(OpName);
|
|
||||||
std::vector<std::string> &OpVTs = OpVTI->second;
|
|
||||||
OS << " case " << OpcodeInfo.getEnumName() << ": {\n";
|
|
||||||
if (OpVTs.size() == 1) {
|
|
||||||
std::string &VTStr = OpVTs[0];
|
|
||||||
OS << " Select_" << OpName
|
|
||||||
<< (VTStr != "" ? "_" : "") << VTStr << "(Result, N);\n";
|
|
||||||
} else {
|
|
||||||
if (OpcodeInfo.getNumResults())
|
|
||||||
OS << " MVT::ValueType NVT = N.Val->getValueType(0);\n";
|
|
||||||
else if (OpcodeInfo.hasProperty(SDNodeInfo::SDNPHasChain))
|
|
||||||
OS << " MVT::ValueType NVT = (N.getNumOperands() > 1) ?"
|
|
||||||
<< " N.getOperand(1).Val->getValueType(0) : MVT::isVoid;\n";
|
|
||||||
else
|
|
||||||
OS << " MVT::ValueType NVT = (N.getNumOperands() > 0) ?"
|
|
||||||
<< " N.getOperand(0).Val->getValueType(0) : MVT::isVoid;\n";
|
|
||||||
int ElseCase = -1;
|
|
||||||
bool First = true;
|
|
||||||
for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
|
|
||||||
std::string &VTStr = OpVTs[i];
|
|
||||||
if (VTStr == "") {
|
|
||||||
ElseCase = i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
OS << (First ? " if" : " else if")
|
|
||||||
<< " (NVT == MVT::" << VTStr << ")\n"
|
|
||||||
<< " Select_" << OpName
|
|
||||||
<< "_" << VTStr << "(Result, N);\n";
|
|
||||||
First = false;
|
|
||||||
}
|
|
||||||
if (ElseCase != -1)
|
|
||||||
OS << " else\n" << " Select_" << OpName << "(Result, N);\n";
|
|
||||||
else
|
|
||||||
OS << " else\n" << " break;\n";
|
|
||||||
}
|
|
||||||
OS << " return;\n";
|
|
||||||
OS << " }\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << " } // end of big switch.\n\n"
|
OS << " } // end of big switch.\n\n"
|
||||||
@ -3547,93 +3633,112 @@ void DAGISelEmitter::run(std::ostream &OS) {
|
|||||||
OS << "#if defined(__GNUC__) && \\\n";
|
OS << "#if defined(__GNUC__) && \\\n";
|
||||||
OS << " ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))\n";
|
OS << " ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))\n";
|
||||||
OS << "#define NOINLINE __attribute__((noinline))\n";
|
OS << "#define NOINLINE __attribute__((noinline))\n";
|
||||||
OS << "#else\n";
|
|
||||||
OS << "#define NOINLINE\n";
|
|
||||||
OS << "#endif\n\n";
|
OS << "#endif\n\n";
|
||||||
|
|
||||||
OS << "// Instruction selector priority queue:\n"
|
OS << "// Instance var to keep track of multiply used nodes that have \n"
|
||||||
<< "std::vector<SDNode*> ISelQueue;\n";
|
<< "// already been selected.\n"
|
||||||
OS << "/// Keep track of nodes which have already been added to queue.\n"
|
<< "std::map<SDOperand, SDOperand> CodeGenMap;\n";
|
||||||
<< "unsigned char *ISelQueued;\n";
|
|
||||||
OS << "/// Keep track of nodes which have already been selected.\n"
|
|
||||||
<< "unsigned char *ISelSelected;\n";
|
|
||||||
OS << "/// Dummy parameter to ReplaceAllUsesOfValueWith().\n"
|
|
||||||
<< "std::vector<SDNode*> ISelKilled;\n\n";
|
|
||||||
|
|
||||||
OS << "/// Sorting functions for the selection queue.\n"
|
OS << "// Instance var to keep track of mapping of chain generating nodes\n"
|
||||||
<< "struct isel_sort : public std::binary_function"
|
<< "// and their place handle nodes.\n";
|
||||||
<< "<SDNode*, SDNode*, bool> {\n"
|
OS << "std::map<SDOperand, SDOperand> HandleMap;\n";
|
||||||
<< " bool operator()(const SDNode* left, const SDNode* right) "
|
OS << "// Instance var to keep track of mapping of place handle nodes\n"
|
||||||
<< "const {\n"
|
<< "// and their replacement nodes.\n";
|
||||||
<< " return (left->getNodeId() > right->getNodeId());\n"
|
OS << "std::map<SDOperand, SDOperand> ReplaceMap;\n";
|
||||||
<< " }\n"
|
OS << "// Keep track of nodes that are currently being selecte and therefore\n"
|
||||||
<< "};\n\n";
|
<< "// should not be folded.\n";
|
||||||
|
OS << "std::set<SDNode*> InFlightSet;\n";
|
||||||
|
|
||||||
OS << "inline void setQueued(int Id) {\n";
|
OS << "\n";
|
||||||
OS << " ISelQueued[Id / 8] |= 1 << (Id % 8);\n";
|
OS << "static void findNonImmUse(SDNode* Use, SDNode* Def, bool &found, "
|
||||||
OS << "}\n";
|
<< "std::set<SDNode *> &Visited) {\n";
|
||||||
OS << "inline bool isQueued(int Id) {\n";
|
OS << " if (found || !Visited.insert(Use).second) return;\n";
|
||||||
OS << " return ISelQueued[Id / 8] & (1 << (Id % 8));\n";
|
OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {\n";
|
||||||
OS << "}\n";
|
OS << " SDNode *N = Use->getOperand(i).Val;\n";
|
||||||
OS << "inline void setSelected(int Id) {\n";
|
OS << " if (N != Def) {\n";
|
||||||
OS << " ISelSelected[Id / 8] |= 1 << (Id % 8);\n";
|
OS << " findNonImmUse(N, Def, found, Visited);\n";
|
||||||
OS << "}\n";
|
OS << " } else {\n";
|
||||||
OS << "inline bool isSelected(int Id) {\n";
|
OS << " found = true;\n";
|
||||||
OS << " return ISelSelected[Id / 8] & (1 << (Id % 8));\n";
|
OS << " break;\n";
|
||||||
OS << "}\n\n";
|
|
||||||
|
|
||||||
OS << "inline void AddToQueue(SDOperand &Result, SDOperand N) {\n";
|
|
||||||
OS << " Result = N;\n";
|
|
||||||
OS << " int Id = N.Val->getNodeId();\n";
|
|
||||||
OS << " if (Id != -1 && !isQueued(Id)) {\n";
|
|
||||||
OS << " ISelQueue.push_back(N.Val);\n";
|
|
||||||
OS << " std::push_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
|
|
||||||
OS << " setQueued(Id);\n";
|
|
||||||
OS << " }\n";
|
OS << " }\n";
|
||||||
OS << "}\n\n";
|
|
||||||
|
|
||||||
OS << "inline void RemoveKilled() {\n";
|
|
||||||
OS << " unsigned NumKilled = ISelKilled.size();\n";
|
|
||||||
OS << " if (NumKilled) {\n";
|
|
||||||
OS << " for (unsigned i = 0; i != NumKilled; ++i) {\n";
|
|
||||||
OS << " SDNode *Temp = ISelKilled[i];\n";
|
|
||||||
OS << " std::remove(ISelQueue.begin(), ISelQueue.end(), Temp);\n";
|
|
||||||
OS << " };\n";
|
|
||||||
OS << " std::make_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
|
|
||||||
OS << " ISelKilled.clear();\n";
|
|
||||||
OS << " }\n";
|
OS << " }\n";
|
||||||
OS << "}\n\n";
|
OS << "}\n";
|
||||||
|
|
||||||
OS << "inline void ReplaceUses(SDOperand F, SDOperand T) {\n";
|
OS << "\n";
|
||||||
OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, ISelKilled);\n";
|
OS << "static bool isNonImmUse(SDNode* Use, SDNode* Def) {\n";
|
||||||
OS << " setSelected(F.Val->getNodeId());\n";
|
OS << " std::set<SDNode *> Visited;\n";
|
||||||
OS << " RemoveKilled();\n";
|
OS << " bool found = false;\n";
|
||||||
OS << "}\n\n";
|
OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {\n";
|
||||||
|
OS << " SDNode *N = Use->getOperand(i).Val;\n";
|
||||||
|
OS << " if (N != Def) {\n";
|
||||||
|
OS << " findNonImmUse(N, Def, found, Visited);\n";
|
||||||
|
OS << " if (found) break;\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << " return found;\n";
|
||||||
|
OS << "}\n";
|
||||||
|
|
||||||
|
OS << "\n";
|
||||||
|
OS << "// AddHandleReplacement - Note the pending replacement node for a\n"
|
||||||
|
<< "// handle node in ReplaceMap.\n";
|
||||||
|
OS << "void AddHandleReplacement(SDNode *H, unsigned HNum, SDNode *R, "
|
||||||
|
<< "unsigned RNum) {\n";
|
||||||
|
OS << " SDOperand N(H, HNum);\n";
|
||||||
|
OS << " std::map<SDOperand, SDOperand>::iterator HMI = HandleMap.find(N);\n";
|
||||||
|
OS << " if (HMI != HandleMap.end()) {\n";
|
||||||
|
OS << " ReplaceMap[HMI->second] = SDOperand(R, RNum);\n";
|
||||||
|
OS << " HandleMap.erase(N);\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << "}\n";
|
||||||
|
|
||||||
|
OS << "\n";
|
||||||
|
OS << "// SelectDanglingHandles - Select replacements for all `dangling`\n";
|
||||||
|
OS << "// handles.Some handles do not yet have replacements because the\n";
|
||||||
|
OS << "// nodes they replacements have only dead readers.\n";
|
||||||
|
OS << "void SelectDanglingHandles() {\n";
|
||||||
|
OS << " for (std::map<SDOperand, SDOperand>::iterator I = "
|
||||||
|
<< "HandleMap.begin(),\n"
|
||||||
|
<< " E = HandleMap.end(); I != E; ++I) {\n";
|
||||||
|
OS << " SDOperand N = I->first;\n";
|
||||||
|
OS << " SDOperand R;\n";
|
||||||
|
OS << " Select(R, N.getValue(0));\n";
|
||||||
|
OS << " AddHandleReplacement(N.Val, N.ResNo, R.Val, R.ResNo);\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << "}\n";
|
||||||
|
OS << "\n";
|
||||||
|
OS << "// ReplaceHandles - Replace all the handles with the real target\n";
|
||||||
|
OS << "// specific nodes.\n";
|
||||||
|
OS << "void ReplaceHandles() {\n";
|
||||||
|
OS << " for (std::map<SDOperand, SDOperand>::iterator I = "
|
||||||
|
<< "ReplaceMap.begin(),\n"
|
||||||
|
<< " E = ReplaceMap.end(); I != E; ++I) {\n";
|
||||||
|
OS << " SDOperand From = I->first;\n";
|
||||||
|
OS << " SDOperand To = I->second;\n";
|
||||||
|
OS << " for (SDNode::use_iterator UI = From.Val->use_begin(), "
|
||||||
|
<< "E = From.Val->use_end(); UI != E; ++UI) {\n";
|
||||||
|
OS << " SDNode *Use = *UI;\n";
|
||||||
|
OS << " std::vector<SDOperand> Ops;\n";
|
||||||
|
OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i){\n";
|
||||||
|
OS << " SDOperand O = Use->getOperand(i);\n";
|
||||||
|
OS << " if (O.Val == From.Val)\n";
|
||||||
|
OS << " Ops.push_back(To);\n";
|
||||||
|
OS << " else\n";
|
||||||
|
OS << " Ops.push_back(O);\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << " SDOperand U = SDOperand(Use, 0);\n";
|
||||||
|
OS << " CurDAG->UpdateNodeOperands(U, Ops);\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << " }\n";
|
||||||
|
OS << "}\n";
|
||||||
|
|
||||||
|
OS << "\n";
|
||||||
OS << "// SelectRoot - Top level entry to DAG isel.\n";
|
OS << "// SelectRoot - Top level entry to DAG isel.\n";
|
||||||
OS << "SDOperand SelectRoot(SDOperand Root) {\n";
|
OS << "SDOperand SelectRoot(SDOperand N) {\n";
|
||||||
OS << " SelectRootInit();\n";
|
|
||||||
OS << " unsigned NumBytes = (DAGSize + 7) / 8;\n";
|
|
||||||
OS << " ISelQueued = new unsigned char[NumBytes];\n";
|
|
||||||
OS << " ISelSelected = new unsigned char[NumBytes];\n";
|
|
||||||
OS << " memset(ISelQueued, 0, NumBytes);\n";
|
|
||||||
OS << " memset(ISelSelected, 0, NumBytes);\n";
|
|
||||||
OS << "\n";
|
|
||||||
OS << " SDOperand ResNode;\n";
|
OS << " SDOperand ResNode;\n";
|
||||||
OS << " Select(ResNode, Root);\n";
|
OS << " Select(ResNode, N);\n";
|
||||||
OS << " while (!ISelQueue.empty()) {\n";
|
OS << " SelectDanglingHandles();\n";
|
||||||
OS << " SDOperand Tmp;\n";
|
OS << " ReplaceHandles();\n";
|
||||||
OS << " SDNode *Node = ISelQueue.front();\n";
|
OS << " ReplaceMap.clear();\n";
|
||||||
OS << " std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
|
|
||||||
OS << " ISelQueue.pop_back();\n";
|
|
||||||
OS << " if (!isSelected(Node->getNodeId()))\n";
|
|
||||||
OS << " Select(Tmp, SDOperand(Node, 0));\n";
|
|
||||||
OS << " }\n";
|
|
||||||
OS << "\n";
|
|
||||||
OS << " delete[] ISelQueued;\n";
|
|
||||||
OS << " ISelQueued = NULL;\n";
|
|
||||||
OS << " delete[] ISelSelected;\n";
|
|
||||||
OS << " ISelSelected = NULL;\n";
|
|
||||||
OS << " return ResNode;\n";
|
OS << " return ResNode;\n";
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user