#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Streams.h"
#include <algorithm>
#include <set>
using namespace llvm;
x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum =
R->getValueAsInt("OtherOpNum");
} else {
- std::cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
+ cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
exit(1);
}
}
"We only work with nodes with zero or one result so far!");
if (OpNo >= (NumResults + N->getNumChildren())) {
- std::cerr << "Invalid operand number " << OpNo << " ";
+ cerr << "Invalid operand number " << OpNo << " ";
N->dump();
- std::cerr << '\n';
+ cerr << '\n';
exit(1);
}
} else if (PropList[i]->getName() == "SDNPOptInFlag") {
Properties |= 1 << SDNPOptInFlag;
} else {
- std::cerr << "Unknown SD Node property '" << PropList[i]->getName()
- << "' on node '" << R->getName() << "'!\n";
+ cerr << "Unknown SD Node property '" << PropList[i]->getName()
+ << "' on node '" << R->getName() << "'!\n";
exit(1);
}
}
if (isLeaf()) {
dump();
- std::cerr << " ";
+ cerr << " ";
TP.error("Type inference contradiction found in node!");
} else {
TP.error("Type inference contradiction found in node " +
}
void TreePatternNode::dump() const {
- print(std::cerr);
+ print(*cerr.stream());
}
/// isIsomorphicTo - Return true if this node is recursively isomorphic to
error("Constant int argument should not have a name!");
Children.push_back(Node);
} else {
- std::cerr << '"';
+ cerr << '"';
Arg->dump();
- std::cerr << "\": ";
+ cerr << "\": ";
error("Unknown leaf value for tree pattern!");
}
}
OS << "]\n";
}
-void TreePattern::dump() const { print(std::cerr); }
+void TreePattern::dump() const { print(*cerr.stream()); }
if (I == 0) continue; // No pattern.
if (I->getNumTrees() != 1) {
- std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
+ cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
continue;
}
TreePatternNode *Pattern = I->getTree(0);
// match multiple ways. Add them to PatternsToMatch as well.
void DAGISelEmitter::GenerateVariants() {
- DEBUG(std::cerr << "Generating instruction variants.\n");
+ DOUT << "Generating instruction variants.\n";
// Loop over all of the patterns we've collected, checking to see if we can
// generate variants of the instruction, through the exploitation of
if (Variants.empty()) // No variants for this pattern.
continue;
- DEBUG(std::cerr << "FOUND VARIANTS OF: ";
- PatternsToMatch[i].getSrcPattern()->dump();
- std::cerr << "\n");
+ DOUT << "FOUND VARIANTS OF: ";
+ DEBUG(PatternsToMatch[i].getSrcPattern()->dump());
+ DOUT << "\n";
for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
TreePatternNode *Variant = Variants[v];
- DEBUG(std::cerr << " VAR#" << v << ": ";
- Variant->dump();
- std::cerr << "\n");
+ DOUT << " VAR#" << v << ": ";
+ DEBUG(Variant->dump());
+ DOUT << "\n";
// Scan to see if an instruction or explicit pattern already matches this.
bool AlreadyExists = false;
for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
// Check to see if this variant already exists.
if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern())) {
- DEBUG(std::cerr << " *** ALREADY EXISTS, ignoring variant.\n");
+ DOUT << " *** ALREADY EXISTS, ignoring variant.\n";
AlreadyExists = true;
break;
}
PatternsToMatch[i].getAddedComplexity()));
}
- DEBUG(std::cerr << "\n");
+ DOUT << "\n";
}
}
Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const {
Record *N = Records.getDef(Name);
if (!N || !N->isSubClassOf("SDNode")) {
- std::cerr << "Error getting SDNode '" << Name << "'!\n";
+ cerr << "Error getting SDNode '" << Name << "'!\n";
exit(1);
}
return N;
} else {
#ifndef NDEBUG
Child->dump();
- std::cerr << " ";
+ cerr << " ";
#endif
assert(0 && "Unknown leaf type!");
}
assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
std::string CastType;
switch (N->getTypeNum(0)) {
- default: assert(0 && "Unknown type for constant node!");
+ default:
+ cerr << "Cannot handle " << getEnumName(N->getTypeNum(0))
+ << " type as an immediate constant. Aborting\n";
+ abort();
case MVT::i1: CastType = "bool"; break;
case MVT::i8: CastType = "unsigned char"; break;
case MVT::i16: CastType = "unsigned short"; break;
} else {
NodeOps.push_back(Val);
}
- } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") {
+ } else if (!N->isLeaf() && (N->getOperator()->getName() == "tglobaladdr"
+ || N->getOperator()->getName() == "tglobaltlsaddr")) {
Record *Op = OperatorMap[N->getName()];
// Transform GlobalAddress to TargetGlobalAddress
- if (Op && Op->getName() == "globaladdr") {
+ if (Op && (Op->getName() == "globaladdr" ||
+ Op->getName() == "globaltlsaddr")) {
emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
"GlobalAddress(cast<GlobalAddressSDNode>(" + Val +
")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
Code2 = "SDOperand " + NodeName + " = SDOperand(";
} else {
NodeName = "ResNode";
- if (!ResNodeDecled)
+ if (!ResNodeDecled) {
Code2 = "SDNode *" + NodeName + " = ";
- else
+ ResNodeDecled = true;
+ } else
Code2 = NodeName + " = ";
}
return NodeOps;
} else {
N->dump();
- std::cerr << "\n";
+ cerr << "\n";
throw std::string("Unknown node in result pattern!");
}
}
}
void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
- std::string InstNS = Target.inst_begin()->second.Namespace;
+ // Get the namespace to insert instructions into. Make sure not to pick up
+ // "TargetInstrInfo" by accidentally getting the namespace off the PHI
+ // instruction or something.
+ std::string InstNS;
+ for (CodeGenTarget::inst_iterator i = Target.inst_begin(),
+ e = Target.inst_end(); i != e; ++i) {
+ InstNS = i->second.Namespace;
+ if (InstNS != "TargetInstrInfo")
+ break;
+ }
+
if (!InstNS.empty()) InstNS += "::";
// Group the patterns by their top-level opcodes.
&PatternsToMatch[i]);
}
} else {
- std::cerr << "Unrecognized opcode '";
+ cerr << "Unrecognized opcode '";
Node->dump();
- std::cerr << "' on tree pattern '";
- std::cerr <<
- PatternsToMatch[i].getDstPattern()->getOperator()->getName();
- std::cerr << "'!\n";
+ cerr << "' on tree pattern '";
+ cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName();
+ cerr << "'!\n";
exit(1);
}
}
// If this pattern definitely matches, and if it isn't the last one, the
// patterns after it CANNOT ever match. Error out.
if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
- std::cerr << "Pattern '";
- CodeForPatterns[i].first->getSrcPattern()->print(std::cerr);
- std::cerr << "' is impossible to select!\n";
+ cerr << "Pattern '";
+ CodeForPatterns[i].first->getSrcPattern()->print(*cerr.stream());
+ cerr << "' is impossible to select!\n";
exit(1);
}
}
// Print function.
std::string OpVTStr;
- if (OpVT == MVT::iPTR)
- OpVTStr = "iPTR";
- else
- OpVTStr = getEnumName(OpVT).substr(5); // Skip 'MVT::'
+ if (OpVT == MVT::iPTR) {
+ OpVTStr = "_iPTR";
+ } else if (OpVT == MVT::isVoid) {
+ // Nodes with a void result actually have a first result type of either
+ // Other (a chain) or Flag. Since there is no one-to-one mapping from
+ // void to this case, we handle it specially here.
+ } else {
+ OpVTStr = "_" + getEnumName(OpVT).substr(5); // Skip 'MVT::'
+ }
std::map<std::string, std::vector<std::string> >::iterator OpVTI =
OpcodeVTMap.find(OpName);
if (OpVTI == OpcodeVTMap.end()) {
OpVTI->second.push_back(OpVTStr);
OS << "SDNode *Select_" << getLegalCName(OpName)
- << "_" << OpVTStr << "(const SDOperand &N) {\n";
+ << OpVTStr << "(const SDOperand &N) {\n";
// Loop through and reverse all of the CodeList vectors, as we will be
// accessing them from their logical front, but accessing the end of a
// If the last pattern has predicates (which could fail) emit code to
// catch the case where nothing handles a pattern.
if (mightNotMatch) {
- OS << " std::cerr << \"Cannot yet select: \";\n";
+ OS << " cerr << \"Cannot yet select: \";\n";
if (OpName != "ISD::INTRINSIC_W_CHAIN" &&
OpName != "ISD::INTRINSIC_WO_CHAIN" &&
OpName != "ISD::INTRINSIC_VOID") {
} else {
OS << " unsigned iid = cast<ConstantSDNode>(N.getOperand("
"N.getOperand(0).getValueType() == MVT::Other))->getValue();\n"
- << " std::cerr << \"intrinsic %\"<< "
+ << " cerr << \"intrinsic %\"<< "
"Intrinsic::getName((Intrinsic::ID)iid);\n";
}
- OS << " std::cerr << '\\n';\n"
+ OS << " cerr << '\\n';\n"
<< " abort();\n"
<< " return NULL;\n";
}
<< " return New.Val;\n"
<< "}\n\n";
+ OS << "SDNode *Select_LABEL(const SDOperand &N) {\n"
+ << " SDOperand Chain = N.getOperand(0);\n"
+ << " SDOperand N1 = N.getOperand(1);\n"
+ << " unsigned C = cast<ConstantSDNode>(N1)->getValue();\n"
+ << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n"
+ << " AddToISelQueue(Chain);\n"
+ << " return CurDAG->getTargetNode(TargetInstrInfo::LABEL,\n"
+ << " MVT::Other, Tmp, Chain);\n"
+ << "}\n\n";
+
OS << "// The main instruction selector code.\n"
<< "SDNode *SelectCode(SDOperand N) {\n"
<< " if (N.getOpcode() >= ISD::BUILTIN_OP_END &&\n"
<< " case ISD::TargetConstantPool:\n"
<< " case ISD::TargetFrameIndex:\n"
<< " case ISD::TargetJumpTable:\n"
+ << " case ISD::TargetGlobalTLSAddress:\n"
<< " case ISD::TargetGlobalAddress: {\n"
<< " return NULL;\n"
<< " }\n"
<< " AddToISelQueue(N.getOperand(i));\n"
<< " return NULL;\n"
<< " }\n"
- << " case ISD::INLINEASM: return Select_INLINEASM(N);\n";
+ << " case ISD::INLINEASM: return Select_INLINEASM(N);\n"
+ << " case ISD::LABEL: return Select_LABEL(N);\n";
// Loop over all of the case statements, emiting a call to each method we
if (OpVTs.size() == 1) {
std::string &VTStr = OpVTs[0];
OS << " return Select_" << getLegalCName(OpName)
- << (VTStr != "" ? "_" : "") << VTStr << "(N);\n";
+ << VTStr << "(N);\n";
} else {
+ // Keep track of whether we see a pattern that has an iPtr result.
+ bool HasPtrPattern = false;
+ bool HasDefaultPattern = false;
+
OS << " switch (NVT) {\n";
for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
std::string &VTStr = OpVTs[i];
- assert(!VTStr.empty() && "Unset vtstr?");
- OS << " case MVT::" << VTStr << ":\n"
+ if (VTStr.empty()) {
+ HasDefaultPattern = true;
+ continue;
+ }
+
+ // If this is a match on iPTR: don't emit it directly, we need special
+ // code.
+ if (VTStr == "_iPTR") {
+ HasPtrPattern = true;
+ continue;
+ }
+ OS << " case MVT::" << VTStr.substr(1) << ":\n"
<< " return Select_" << getLegalCName(OpName)
- << "_" << VTStr << "(N);\n";
+ << VTStr << "(N);\n";
}
OS << " default:\n";
+
+ // If there is an iPTR result version of this pattern, emit it here.
+ if (HasPtrPattern) {
+ OS << " if (NVT == TLI.getPointerTy())\n";
+ OS << " return Select_" << getLegalCName(OpName) <<"_iPTR(N);\n";
+ }
+ if (HasDefaultPattern) {
+ OS << " return Select_" << getLegalCName(OpName) << "(N);\n";
+ }
OS << " break;\n";
OS << " }\n";
OS << " break;\n";
}
OS << " } // end of big switch.\n\n"
- << " std::cerr << \"Cannot yet select: \";\n"
+ << " cerr << \"Cannot yet select: \";\n"
<< " if (N.getOpcode() != ISD::INTRINSIC_W_CHAIN &&\n"
<< " N.getOpcode() != ISD::INTRINSIC_WO_CHAIN &&\n"
<< " N.getOpcode() != ISD::INTRINSIC_VOID) {\n"
<< " } else {\n"
<< " unsigned iid = cast<ConstantSDNode>(N.getOperand("
"N.getOperand(0).getValueType() == MVT::Other))->getValue();\n"
- << " std::cerr << \"intrinsic %\"<< "
- "Intrinsic::getName((Intrinsic::ID)iid);\n"
+ << " cerr << \"intrinsic %\"<< "
+ "Intrinsic::getName((Intrinsic::ID)iid);\n"
<< " }\n"
- << " std::cerr << '\\n';\n"
+ << " cerr << '\\n';\n"
<< " abort();\n"
<< " return NULL;\n"
<< "}\n";
// multiple ways. Add them to PatternsToMatch as well.
GenerateVariants();
-
- DEBUG(std::cerr << "\n\nALL PATTERNS TO MATCH:\n\n";
- for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
- std::cerr << "PATTERN: "; PatternsToMatch[i].getSrcPattern()->dump();
- std::cerr << "\nRESULT: ";PatternsToMatch[i].getDstPattern()->dump();
- std::cerr << "\n";
- });
+ DOUT << "\n\nALL PATTERNS TO MATCH:\n\n";
+ for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
+ DOUT << "PATTERN: "; DEBUG(PatternsToMatch[i].getSrcPattern()->dump());
+ DOUT << "\nRESULT: "; DEBUG(PatternsToMatch[i].getDstPattern()->dump());
+ DOUT << "\n";
+ }
// At this point, we have full information about the 'Patterns' we need to
// parse, both implicitly from instructions as well as from explicit pattern