[llvm-commits] [vector_llvm] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp CodeGenTarget.cpp DAGISelEmitter.cpp DAGISelEmitter.h InstrInfoEmitter.cpp InstrInfoEmitter.h InstrSelectorEmitter.cpp InstrSelectorEmitter.h Record.cpp Record.h RegisterInfoEmitter.cpp SubtargetEmitter.cpp SubtargetEmitter.h TableGen.cpp
Robert Bocchino
bocchino at cs.uiuc.edu
Wed Nov 16 10:33:56 PST 2005
Changes in directory llvm/utils/TableGen:
CodeEmitterGen.cpp updated: 1.41 -> 1.41.2.1
CodeGenTarget.cpp updated: 1.40 -> 1.40.2.1
DAGISelEmitter.cpp updated: 1.59 -> 1.59.2.1
DAGISelEmitter.h updated: 1.33 -> 1.33.2.1
InstrInfoEmitter.cpp updated: 1.28 -> 1.28.2.1
InstrInfoEmitter.h updated: 1.10 -> 1.10.2.1
InstrSelectorEmitter.cpp (r1.45) removed
InstrSelectorEmitter.h (r1.27) removed
Record.cpp updated: 1.45 -> 1.45.2.1
Record.h updated: 1.52 -> 1.52.2.1
RegisterInfoEmitter.cpp updated: 1.36 -> 1.36.2.1
SubtargetEmitter.cpp added (r1.14.2.2)
SubtargetEmitter.h added (r1.7.2.2)
TableGen.cpp updated: 1.39 -> 1.39.2.1
---
Log message:
Merged mainline into Vector LLVM branch
---
Diffs of the changes: (+894 -122)
CodeEmitterGen.cpp | 3
CodeGenTarget.cpp | 28 --
DAGISelEmitter.cpp | 242 ++++++++++++++++++----
DAGISelEmitter.h | 17 +
InstrInfoEmitter.cpp | 80 ++++---
InstrInfoEmitter.h | 9
Record.cpp | 19 +
Record.h | 6
RegisterInfoEmitter.cpp | 19 -
SubtargetEmitter.cpp | 516 ++++++++++++++++++++++++++++++++++++++++++++++++
SubtargetEmitter.h | 62 +++++
TableGen.cpp | 15 -
12 files changed, 894 insertions(+), 122 deletions(-)
Index: llvm/utils/TableGen/CodeEmitterGen.cpp
diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.41 llvm/utils/TableGen/CodeEmitterGen.cpp:1.41.2.1
--- llvm/utils/TableGen/CodeEmitterGen.cpp:1.41 Thu Aug 18 20:04:33 2005
+++ llvm/utils/TableGen/CodeEmitterGen.cpp Wed Nov 16 12:33:45 2005
@@ -76,7 +76,6 @@
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
EmitSourceFileHeader("Machine Code Emitter", o);
- o << "namespace llvm {\n\n";
std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
// Emit function declaration
@@ -255,6 +254,4 @@
<< " }\n"
<< " return Value;\n"
<< "}\n\n";
-
- o << "} // End llvm namespace \n";
}
Index: llvm/utils/TableGen/CodeGenTarget.cpp
diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.40 llvm/utils/TableGen/CodeGenTarget.cpp:1.40.2.1
--- llvm/utils/TableGen/CodeGenTarget.cpp:1.40 Thu Oct 13 22:54:49 2005
+++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Nov 16 12:33:45 2005
@@ -84,15 +84,8 @@
throw std::string("ERROR: Multiple subclasses of Target defined!");
TargetRec = Targets[0];
- // Read in all of the CalleeSavedRegisters...
- ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters");
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
- CalleeSavedRegisters.push_back(DI->getDef());
- else
- throw "Target: " + TargetRec->getName() +
- " expected register definition in CalleeSavedRegisters list!";
-
+ // Read in all of the CalleeSavedRegisters.
+ CalleeSavedRegisters =TargetRec->getValueAsListOfDefs("CalleeSavedRegisters");
PointerType = getValueType(TargetRec->getValueAsDef("PointerType"));
}
@@ -108,12 +101,10 @@
/// getAsmWriter - Return the AssemblyWriter definition for this target.
///
Record *CodeGenTarget::getAsmWriter() const {
- ListInit *LI = TargetRec->getValueAsListInit("AssemblyWriters");
- if (AsmWriterNum >= LI->getSize())
+ std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
+ if (AsmWriterNum >= LI.size())
throw "Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!";
- DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(AsmWriterNum));
- if (!DI) throw std::string("AssemblyWriter list should be a list of defs!");
- return DI->getDef();
+ return LI[AsmWriterNum];
}
void CodeGenTarget::ReadRegisters() const {
@@ -159,12 +150,9 @@
MethodBodies = R->getValueAsCode("MethodBodies");
MethodProtos = R->getValueAsCode("MethodProtos");
- ListInit *RegList = R->getValueAsListInit("MemberList");
- for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
- DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
- if (!RegDef) throw "Register class member is not a record!";
- Record *Reg = RegDef->getDef();
-
+ std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
+ for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
+ Record *Reg = RegList[i];
if (!Reg->isSubClassOf("Register"))
throw "Register Class member '" + Reg->getName() +
"' does not derive from the Register class!";
Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.59 llvm/utils/TableGen/DAGISelEmitter.cpp:1.59.2.1
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.59 Mon Oct 17 23:41:01 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Nov 16 12:33:45 2005
@@ -228,16 +228,14 @@
// Parse the properties.
Properties = 0;
- ListInit *LI = R->getValueAsListInit("Properties");
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i) {
- DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i));
- assert(DI && "Properties list must be list of defs!");
- if (DI->getDef()->getName() == "SDNPCommutative") {
+ std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
+ for (unsigned i = 0, e = PropList.size(); i != e; ++i) {
+ if (PropList[i]->getName() == "SDNPCommutative") {
Properties |= 1 << SDNPCommutative;
- } else if (DI->getDef()->getName() == "SDNPAssociative") {
+ } else if (PropList[i]->getName() == "SDNPAssociative") {
Properties |= 1 << SDNPAssociative;
} else {
- std::cerr << "Unknown SD Node property '" << DI->getDef()->getName()
+ std::cerr << "Unknown SD Node property '" << PropList[i]->getName()
<< "' on node '" << R->getName() << "'!\n";
exit(1);
}
@@ -245,14 +243,9 @@
// Parse the type constraints.
- ListInit *Constraints = TypeProfile->getValueAsListInit("Constraints");
- for (unsigned i = 0, e = Constraints->getSize(); i != e; ++i) {
- assert(dynamic_cast<DefInit*>(Constraints->getElement(i)) &&
- "Constraints list should contain constraint definitions!");
- Record *Constraint =
- static_cast<DefInit*>(Constraints->getElement(i))->getDef();
- TypeConstraints.push_back(Constraint);
- }
+ std::vector<Record*> ConstraintList =
+ TypeProfile->getValueAsListOfDefs("Constraints");
+ TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
}
//===----------------------------------------------------------------------===//
@@ -291,8 +284,13 @@
return true;
}
- TP.error("Type inference contradiction found in node " +
- getOperator()->getName() + "!");
+ if (isLeaf()) {
+ dump();
+ TP.error("Type inference contradiction found in node!");
+ } else {
+ TP.error("Type inference contradiction found in node " +
+ getOperator()->getName() + "!");
+ }
return true; // unreachable
}
@@ -462,10 +460,12 @@
// Pattern fragment types will be resolved when they are inlined.
return MVT::isUnknown;
} else if (R->isSubClassOf("Register")) {
- assert(0 && "Explicit registers not handled here yet!\n");
+ //const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo();
+ // TODO: if a register appears in exactly one regclass, we could use that
+ // type info.
return MVT::isUnknown;
- } else if (R->isSubClassOf("ValueType")) {
- // Using a VTSDNode.
+ } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
+ // Using a VTSDNode or CondCodeSDNode.
return MVT::Other;
} else if (R->getName() == "node") {
// Placeholder.
@@ -482,10 +482,28 @@
/// exception.
bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
if (isLeaf()) {
- if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue()))
+ if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
// If it's a regclass or something else known, include the type.
return UpdateNodeType(getIntrinsicType(DI->getDef(), NotRegisters, TP),
TP);
+ } else if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
+ // Int inits are always integers. :)
+ bool MadeChange = UpdateNodeType(MVT::isInt, TP);
+
+ if (hasTypeSet()) {
+ unsigned Size = MVT::getSizeInBits(getType());
+ // Make sure that the value is representable for this type.
+ if (Size < 32) {
+ int Val = (II->getValue() << (32-Size)) >> (32-Size);
+ if (Val != II->getValue())
+ TP.error("Sign-extended integer value '" + itostr(II->getValue()) +
+ "' is out of range for type 'MVT::" +
+ getEnumName(getType()) + "'!");
+ }
+ }
+
+ return MadeChange;
+ }
return false;
}
@@ -571,19 +589,22 @@
// TreePattern implementation
//
-TreePattern::TreePattern(Record *TheRec, ListInit *RawPat,
+TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+ isInputPattern = isInput;
for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
}
-TreePattern::TreePattern(Record *TheRec, DagInit *Pat,
+TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+ isInputPattern = isInput;
Trees.push_back(ParseTreePattern(Pat));
}
-TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat,
+TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+ isInputPattern = isInput;
Trees.push_back(Pat);
}
@@ -618,6 +639,10 @@
New = new TreePatternNode(DI);
} else if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
New = ParseTreePattern(DI);
+ } else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+ New = new TreePatternNode(II);
+ if (!Dag->getArgName(0).empty())
+ error("Constant int argument should not have a name!");
} else {
Arg->dump();
error("Unknown leaf value for tree pattern!");
@@ -636,6 +661,11 @@
Operator->getName() != "set")
error("Unrecognized node '" + Operator->getName() + "'!");
+ // Check to see if this is something that is illegal in an input pattern.
+ if (isInputPattern && (Operator->isSubClassOf("Instruction") ||
+ Operator->isSubClassOf("SDNodeXForm")))
+ error("Cannot use '" + Operator->getName() + "' in an input pattern!");
+
std::vector<TreePatternNode*> Children;
for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
@@ -663,8 +693,15 @@
Args.push_back(Dag->getArgName(i));
}
}
+ } else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+ TreePatternNode *Node = new TreePatternNode(II);
+ if (!Dag->getArgName(i).empty())
+ error("Constant int argument should not have a name!");
+ Children.push_back(Node);
} else {
+ std::cerr << '"';
Arg->dump();
+ std::cerr << "\": ";
error("Unknown leaf value for tree pattern!");
}
}
@@ -771,7 +808,7 @@
OS << "\n// Predicate functions.\n";
for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
- TreePattern *P = new TreePattern(Fragments[i], Tree, *this);
+ TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this);
PatternFragments[Fragments[i]] = P;
// Validate the argument list, converting it to map, to discard duplicates.
@@ -975,14 +1012,39 @@
std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
- if (!dynamic_cast<ListInit*>(Instrs[i]->getValueInit("Pattern")))
- continue; // no pattern yet, ignore it.
+ ListInit *LI = 0;
- ListInit *LI = Instrs[i]->getValueAsListInit("Pattern");
- if (LI->getSize() == 0) continue; // no pattern.
+ if (dynamic_cast<ListInit*>(Instrs[i]->getValueInit("Pattern")))
+ LI = Instrs[i]->getValueAsListInit("Pattern");
+
+ // If there is no pattern, only collect minimal information about the
+ // instruction for its operand list. We have to assume that there is one
+ // result, as we have no detailed info.
+ if (!LI || LI->getSize() == 0) {
+ std::vector<MVT::ValueType> ResultTypes;
+ std::vector<MVT::ValueType> OperandTypes;
+
+ CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName());
+
+ // Doesn't even define a result?
+ if (InstInfo.OperandList.size() == 0)
+ continue;
+
+ // Assume the first operand is the result.
+ ResultTypes.push_back(InstInfo.OperandList[0].Ty);
+
+ // The rest are inputs.
+ for (unsigned j = 1, e = InstInfo.OperandList.size(); j != e; ++j)
+ OperandTypes.push_back(InstInfo.OperandList[j].Ty);
+
+ // Create and insert the instruction.
+ Instructions.insert(std::make_pair(Instrs[i],
+ DAGInstruction(0, ResultTypes, OperandTypes)));
+ continue; // no pattern.
+ }
// Parse the instruction.
- TreePattern *I = new TreePattern(Instrs[i], LI, *this);
+ TreePattern *I = new TreePattern(Instrs[i], LI, true, *this);
// Inline pattern fragments into it.
I->InlinePatternFragments();
@@ -1099,7 +1161,7 @@
// Use a temporary tree pattern to infer all types and make sure that the
// constructed result is correct. This depends on the instruction already
// being inserted into the Instructions map.
- TreePattern Temp(I->getRecord(), ResultPattern, *this);
+ TreePattern Temp(I->getRecord(), ResultPattern, false, *this);
Temp.InferAllTypes();
DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second;
@@ -1112,6 +1174,7 @@
for (std::map<Record*, DAGInstruction>::iterator II = Instructions.begin(),
E = Instructions.end(); II != E; ++II) {
TreePattern *I = II->second.getPattern();
+ if (I == 0) continue; // No pattern.
if (I->getNumTrees() != 1) {
std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
@@ -1140,7 +1203,7 @@
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
DagInit *Tree = Patterns[i]->getValueAsDag("PatternToMatch");
- TreePattern *Pattern = new TreePattern(Patterns[i], Tree, *this);
+ TreePattern *Pattern = new TreePattern(Patterns[i], Tree, true, *this);
// Inline pattern fragments into it.
Pattern->InlinePatternFragments();
@@ -1154,7 +1217,7 @@
if (LI->getSize() == 0) continue; // no pattern.
// Parse the instruction.
- TreePattern *Result = new TreePattern(Patterns[i], LI, *this);
+ TreePattern *Result = new TreePattern(Patterns[i], LI, false, *this);
// Inline pattern fragments into it.
Result->InlinePatternFragments();
@@ -1437,6 +1500,9 @@
TreePatternNode *Child = P->getChild(i);
if (!Child->isLeaf() && Child->getExtType() != MVT::Other)
Size += getPatternSize(Child);
+ else if (Child->isLeaf() && dynamic_cast<IntInit*>(Child->getLeafValue())) {
+ ++Size; // Matches a ConstantSDNode.
+ }
}
return Size;
@@ -1477,7 +1543,16 @@
const std::string &RootName,
std::map<std::string,std::string> &VarMap,
unsigned PatternNo, std::ostream &OS) {
- assert(!N->isLeaf() && "Cannot match against a leaf!");
+ if (N->isLeaf()) {
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ OS << " if (cast<ConstantSDNode>(" << RootName
+ << ")->getSignExtended() != " << II->getValue() << ")\n"
+ << " goto P" << PatternNo << "Fail;\n";
+ return;
+ }
+ assert(0 && "Cannot match this as a leaf value!");
+ abort();
+ }
// If this node has a name associated with it, capture it in VarMap. If
// we already saw this in the pattern, emit code to verify dagness.
@@ -1527,15 +1602,29 @@
}
// Handle leaves of various types.
- Init *LeafVal = Child->getLeafValue();
- Record *LeafRec = dynamic_cast<DefInit*>(LeafVal)->getDef();
- if (LeafRec->isSubClassOf("RegisterClass")) {
- // Handle register references. Nothing to do here.
- } else if (LeafRec->isSubClassOf("ValueType")) {
- // Make sure this is the specified value type.
- OS << " if (cast<VTSDNode>(" << RootName << i << ")->getVT() != "
- << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo
- << "Fail;\n";
+ if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+ Record *LeafRec = DI->getDef();
+ if (LeafRec->isSubClassOf("RegisterClass")) {
+ // Handle register references. Nothing to do here.
+ } else if (LeafRec->isSubClassOf("ValueType")) {
+ // Make sure this is the specified value type.
+ OS << " if (cast<VTSDNode>(" << RootName << i << ")->getVT() != "
+ << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo
+ << "Fail;\n";
+ } else if (LeafRec->isSubClassOf("CondCode")) {
+ // Make sure this is the specified cond code.
+ OS << " if (cast<CondCodeSDNode>(" << RootName << i
+ << ")->get() != " << "ISD::" << LeafRec->getName()
+ << ") goto P" << PatternNo << "Fail;\n";
+ } else {
+ Child->dump();
+ assert(0 && "Unknown leaf type!");
+ }
+ } else if (IntInit *II = dynamic_cast<IntInit*>(Child->getLeafValue())) {
+ OS << " if (!isa<ConstantSDNode>(" << RootName << i << ") ||\n"
+ << " cast<ConstantSDNode>(" << RootName << i
+ << ")->getSignExtended() != " << II->getValue() << ")\n"
+ << " goto P" << PatternNo << "Fail;\n";
} else {
Child->dump();
assert(0 && "Unknown leaf type!");
@@ -1589,6 +1678,25 @@
}
if (N->isLeaf()) {
+ // If this is an explicit register reference, handle it.
+ if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+ unsigned ResNo = Ctr++;
+ if (DI->getDef()->isSubClassOf("Register")) {
+ OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister("
+ << getQualifiedName(DI->getDef()) << ", MVT::"
+ << getEnumName(N->getType())
+ << ");\n";
+ return ResNo;
+ }
+ } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ unsigned ResNo = Ctr++;
+ OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant("
+ << II->getValue() << ", MVT::"
+ << getEnumName(N->getType())
+ << ");\n";
+ return ResNo;
+ }
+
N->dump();
assert(0 && "Unknown leaf type!");
return ~0U;
@@ -1685,6 +1793,12 @@
return false;
}
+Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const {
+ Record *N = Records.getDef(Name);
+ assert(N && N->isSubClassOf("SDNode") && "Bad argument");
+ return N;
+}
+
/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
/// stream to match the pattern, and generate the code for the match if it
/// succeeds.
@@ -1785,14 +1899,52 @@
<< " SDOperand Tmp0 = Select(N.getOperand(0));\n"
<< " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp0;\n"
<< " return Tmp0;\n"
+ << " }\n"
+ << " case ISD::TokenFactor:\n"
+ << " if (N.getNumOperands() == 2) {\n"
+ << " SDOperand Op0 = Select(N.getOperand(0));\n"
+ << " SDOperand Op1 = Select(N.getOperand(1));\n"
+ << " return CodeGenMap[N] =\n"
+ << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n"
+ << " } else {\n"
+ << " std::vector<SDOperand> Ops;\n"
+ << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)\n"
+ << " Ops.push_back(Select(N.getOperand(i)));\n"
+ << " return CodeGenMap[N] = \n"
+ << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n"
+ << " }\n"
+ << " case ISD::CopyFromReg: {\n"
+ << " SDOperand Chain = Select(N.getOperand(0));\n"
+ << " if (Chain == N.getOperand(0)) return N; // No change\n"
+ << " SDOperand New = CurDAG->getCopyFromReg(Chain,\n"
+ << " cast<RegisterSDNode>(N.getOperand(1))->getReg(),\n"
+ << " N.Val->getValueType(0));\n"
+ << " return New.getValue(N.ResNo);\n"
+ << " }\n"
+ << " case ISD::CopyToReg: {\n"
+ << " SDOperand Chain = Select(N.getOperand(0));\n"
+ << " SDOperand Reg = N.getOperand(1);\n"
+ << " SDOperand Val = Select(N.getOperand(2));\n"
+ << " return CodeGenMap[N] = \n"
+ << " CurDAG->getNode(ISD::CopyToReg, MVT::Other,\n"
+ << " Chain, Reg, Val);\n"
<< " }\n";
// Group the patterns by their top-level opcodes.
std::map<Record*, std::vector<PatternToMatch*>,
CompareByRecordName> PatternsByOpcode;
for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i)
- PatternsByOpcode[PatternsToMatch[i].first->getOperator()]
- .push_back(&PatternsToMatch[i]);
+ if (!PatternsToMatch[i].first->isLeaf()) {
+ PatternsByOpcode[PatternsToMatch[i].first->getOperator()]
+ .push_back(&PatternsToMatch[i]);
+ } else {
+ if (IntInit *II =
+ dynamic_cast<IntInit*>(PatternsToMatch[i].first->getLeafValue())) {
+ PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]);
+ } else {
+ assert(0 && "Unknown leaf value");
+ }
+ }
// Loop over all of the case statements.
for (std::map<Record*, std::vector<PatternToMatch*>,
Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.33 llvm/utils/TableGen/DAGISelEmitter.h:1.33.2.1
--- llvm/utils/TableGen/DAGISelEmitter.h:1.33 Sat Oct 15 20:41:58 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h Wed Nov 16 12:33:45 2005
@@ -226,7 +226,7 @@
/// ContainsUnresolvedType - Return true if this tree contains any
/// unresolved types.
bool ContainsUnresolvedType() const {
- if (Ty == MVT::LAST_VALUETYPE) return true;
+ if (!hasTypeSet()) return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
if (getChild(i)->ContainsUnresolvedType()) return true;
return false;
@@ -258,13 +258,20 @@
/// ISE - the DAG isel emitter coordinating this madness.
///
DAGISelEmitter &ISE;
+
+ /// isInputPattern - True if this is an input pattern, something to match.
+ /// False if this is an output pattern, something to emit.
+ bool isInputPattern;
public:
/// TreePattern constructor - Parse the specified DagInits into the
/// current record.
- TreePattern(Record *TheRec, ListInit *RawPat, DAGISelEmitter &ise);
- TreePattern(Record *TheRec, DagInit *Pat, DAGISelEmitter &ise);
- TreePattern(Record *TheRec, TreePatternNode *Pat, DAGISelEmitter &ise);
+ TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
+ DAGISelEmitter &ise);
+ TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
+ DAGISelEmitter &ise);
+ TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
+ DAGISelEmitter &ise);
/// getTrees - Return the tree patterns which corresponds to this pattern.
///
@@ -375,6 +382,8 @@
const CodeGenTarget &getTargetInfo() const { return Target; }
+ Record *getSDNodeNamed(const std::string &Name) const;
+
const SDNodeInfo &getSDNodeInfo(Record *R) const {
assert(SDNodes.count(R) && "Unknown node!");
return SDNodes.find(R)->second;
Index: llvm/utils/TableGen/InstrInfoEmitter.cpp
diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28.2.1
--- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28 Fri Aug 26 15:42:52 2005
+++ llvm/utils/TableGen/InstrInfoEmitter.cpp Wed Nov 16 12:33:45 2005
@@ -15,6 +15,7 @@
#include "InstrInfoEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
+#include <algorithm>
using namespace llvm;
// runEnums - Print out enum values for all of the instructions.
@@ -47,16 +48,6 @@
OS << "} // End llvm namespace \n";
}
-static std::vector<Record*> GetDefList(ListInit *LI, const std::string &Name) {
- std::vector<Record*> Result;
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
- Result.push_back(DI->getDef());
- else
- throw "Illegal value in '" + Name + "' list!";
- return Result;
-}
-
void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
unsigned Num, std::ostream &OS) const {
OS << "static const unsigned ImplicitList" << Num << "[] = { ";
@@ -86,6 +77,8 @@
// run - Emit the main instruction description records for the target...
void InstrInfoEmitter::run(std::ostream &OS) {
+ GatherItinClasses();
+
EmitSourceFileHeader("Target Instruction Descriptors", OS);
OS << "namespace llvm {\n\n";
@@ -99,26 +92,21 @@
// Keep track of all of the def lists we have emitted already.
std::map<std::vector<Record*>, unsigned> EmittedLists;
- std::map<ListInit*, unsigned> ListNumbers;
unsigned ListNumber = 0;
// Emit all of the instruction's implicit uses and defs.
for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
E = Target.inst_end(); II != E; ++II) {
Record *Inst = II->second.TheDef;
- ListInit *LI = Inst->getValueAsListInit("Uses");
- if (LI->getSize()) {
- std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
+ std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
+ if (!Uses.empty()) {
unsigned &IL = EmittedLists[Uses];
if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
- ListNumbers[LI] = IL;
}
- LI = Inst->getValueAsListInit("Defs");
- if (LI->getSize()) {
- std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
- unsigned &IL = EmittedLists[Uses];
- if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
- ListNumbers[LI] = IL;
+ std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
+ if (!Defs.empty()) {
+ unsigned &IL = EmittedLists[Defs];
+ if (!IL) printDefList(Defs, IL = ++ListNumber, OS);
}
}
@@ -150,14 +138,14 @@
//
OS << "\nstatic const TargetInstrDescriptor " << TargetName
<< "Insts[] = {\n";
- emitRecord(Target.getPHIInstruction(), 0, InstrInfo, ListNumbers,
+ emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists,
OperandInfosEmitted, OS);
unsigned i = 0;
for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
E = Target.inst_end(); II != E; ++II)
if (II->second.TheDef != PHI)
- emitRecord(II->second, ++i, InstrInfo, ListNumbers,
+ emitRecord(II->second, ++i, InstrInfo, EmittedLists,
OperandInfosEmitted, OS);
OS << "};\n";
OS << "} // End llvm namespace \n";
@@ -165,7 +153,7 @@
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,
- std::map<ListInit*, unsigned> &ListNumbers,
+ std::map<std::vector<Record*>, unsigned> &EmittedLists,
std::map<std::vector<Record*>, unsigned> &OpInfo,
std::ostream &OS) {
int NumOperands;
@@ -183,7 +171,13 @@
OS << Inst.TheDef->getName();
else
OS << Inst.Name;
- OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, 0, 0";
+
+ unsigned ItinClass = !IsItineraries ? 0 :
+ ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());
+
+ OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, "
+ << ItinClass
+ << ", 0";
// Emit all of the target indepedent flags...
if (Inst.isReturn) OS << "|M_RET_FLAG";
@@ -215,17 +209,17 @@
OS << ", ";
// Emit the implicit uses and defs lists...
- LI = Inst.TheDef->getValueAsListInit("Uses");
- if (!LI->getSize())
+ std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
+ if (UseList.empty())
OS << "EmptyImpList, ";
else
- OS << "ImplicitList" << ListNumbers[LI] << ", ";
+ OS << "ImplicitList" << EmittedLists[UseList] << ", ";
- LI = Inst.TheDef->getValueAsListInit("Defs");
- if (!LI->getSize())
+ std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
+ if (DefList.empty())
OS << "EmptyImpList, ";
else
- OS << "ImplicitList" << ListNumbers[LI] << ", ";
+ OS << "ImplicitList" << EmittedLists[DefList] << ", ";
// Emit the operand info.
std::vector<Record*> OperandInfo = GetOperandInfo(Inst);
@@ -237,6 +231,30 @@
OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
}
+struct LessRecord {
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ return Rec1->getName() < Rec2->getName();
+ }
+};
+void InstrInfoEmitter::GatherItinClasses() {
+ std::vector<Record*> DefList =
+ Records.getAllDerivedDefinitions("InstrItinClass");
+ IsItineraries = !DefList.empty();
+
+ if (!IsItineraries) return;
+
+ sort(DefList.begin(), DefList.end(), LessRecord());
+
+ for (unsigned i = 0, N = DefList.size(); i < N; i++) {
+ Record *Def = DefList[i];
+ ItinClassMap[Def->getName()] = i;
+ }
+}
+
+unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) {
+ return ItinClassMap[ItinName];
+}
+
void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
IntInit *ShiftInt, std::ostream &OS) {
if (Val == 0 || ShiftInt == 0)
Index: llvm/utils/TableGen/InstrInfoEmitter.h
diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.10 llvm/utils/TableGen/InstrInfoEmitter.h:1.10.2.1
--- llvm/utils/TableGen/InstrInfoEmitter.h:1.10 Fri Aug 19 13:46:26 2005
+++ llvm/utils/TableGen/InstrInfoEmitter.h Wed Nov 16 12:33:45 2005
@@ -28,8 +28,11 @@
class InstrInfoEmitter : public TableGenBackend {
RecordKeeper &Records;
+ bool IsItineraries;
+ std::map<std::string, unsigned> ItinClassMap;
+
public:
- InstrInfoEmitter(RecordKeeper &R) : Records(R) {}
+ InstrInfoEmitter(RecordKeeper &R) : Records(R), IsItineraries(false) {}
// run - Output the instruction set description, returning true on failure.
void run(std::ostream &OS);
@@ -41,9 +44,11 @@
std::ostream &OS) const;
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,
- std::map<ListInit*, unsigned> &ListNumbers,
+ std::map<std::vector<Record*>, unsigned> &EL,
std::map<std::vector<Record*>, unsigned> &OpInfo,
std::ostream &OS);
+ void GatherItinClasses();
+ unsigned ItinClassNumber(std::string ItinName);
void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift,
std::ostream &OS);
};
Index: llvm/utils/TableGen/Record.cpp
diff -u llvm/utils/TableGen/Record.cpp:1.45 llvm/utils/TableGen/Record.cpp:1.45.2.1
--- llvm/utils/TableGen/Record.cpp:1.45 Tue Sep 13 16:44:28 2005
+++ llvm/utils/TableGen/Record.cpp Wed Nov 16 12:33:45 2005
@@ -709,6 +709,25 @@
"' does not have a list initializer!";
}
+/// getValueAsListOfDefs - This method looks up the specified field and returns
+/// its value as a vector of records, throwing an exception if the field does
+/// not exist or if the value is not the right type.
+///
+std::vector<Record*>
+Record::getValueAsListOfDefs(const std::string &FieldName) const {
+ ListInit *List = getValueAsListInit(FieldName);
+ std::vector<Record*> Defs;
+ for (unsigned i = 0; i < List->getSize(); i++) {
+ if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
+ Defs.push_back(DI->getDef());
+ } else {
+ throw "Record `" + getName() + "', field `" + FieldName +
+ "' list is not entirely DefInit!";
+ }
+ }
+ return Defs;
+}
+
/// getValueAsInt - This method looks up the specified field and returns its
/// value as an int, throwing an exception if the field does not exist or if
/// the value is not the right type.
Index: llvm/utils/TableGen/Record.h
diff -u llvm/utils/TableGen/Record.h:1.52 llvm/utils/TableGen/Record.h:1.52.2.1
--- llvm/utils/TableGen/Record.h:1.52 Tue Sep 13 16:44:28 2005
+++ llvm/utils/TableGen/Record.h Wed Nov 16 12:33:45 2005
@@ -1000,6 +1000,12 @@
///
ListInit *getValueAsListInit(const std::string &FieldName) const;
+ /// getValueAsListOfDefs - This method looks up the specified field and
+ /// returnsits value as a vector of records, throwing an exception if the
+ /// field does not exist or if the value is not the right type.
+ ///
+ std::vector<Record*> getValueAsListOfDefs(const std::string &FieldName) const;
+
/// getValueAsDef - This method looks up the specified field and returns its
/// value as a Record, throwing an exception if the field does not exist or if
/// the value is not the right type.
Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp
diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36.2.1
--- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 Sun Oct 2 01:23:37 2005
+++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Wed Nov 16 12:33:45 2005
@@ -163,23 +163,22 @@
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
Record *R = Regs[i].TheDef;
- ListInit *LI = Regs[i].TheDef->getValueAsListInit("Aliases");
+ std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("Aliases");
// Add information that R aliases all of the elements in the list... and
// that everything in the list aliases R.
- for (unsigned j = 0, e = LI->getSize(); j != e; ++j) {
- DefInit *Reg = dynamic_cast<DefInit*>(LI->getElement(j));
- if (!Reg) throw "ERROR: Alias list element is not a def!";
- if (RegisterAliases[R].count(Reg->getDef()))
+ for (unsigned j = 0, e = LI.size(); j != e; ++j) {
+ Record *Reg = LI[j];
+ if (RegisterAliases[R].count(Reg))
std::cerr << "Warning: register alias between " << getQualifiedName(R)
- << " and " << getQualifiedName(Reg->getDef())
+ << " and " << getQualifiedName(Reg)
<< " specified multiple times!\n";
- RegisterAliases[R].insert(Reg->getDef());
+ RegisterAliases[R].insert(Reg);
- if (RegisterAliases[Reg->getDef()].count(R))
+ if (RegisterAliases[Reg].count(R))
std::cerr << "Warning: register alias between " << getQualifiedName(R)
- << " and " << getQualifiedName(Reg->getDef())
+ << " and " << getQualifiedName(Reg)
<< " specified multiple times!\n";
- RegisterAliases[Reg->getDef()].insert(R);
+ RegisterAliases[Reg].insert(R);
}
}
Index: llvm/utils/TableGen/SubtargetEmitter.cpp
diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.cpp:1.14.2.2
*** /dev/null Wed Nov 16 12:33:56 2005
--- llvm/utils/TableGen/SubtargetEmitter.cpp Wed Nov 16 12:33:45 2005
***************
*** 0 ****
--- 1,516 ----
+ //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by James M. Laskey and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This tablegen backend emits subtarget enumerations. The format is in a state
+ // flux and will be tightened up when integration to scheduling is complete.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "SubtargetEmitter.h"
+ #include "CodeGenTarget.h"
+ #include "Record.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Support/Debug.h"
+ #include <algorithm>
+ using namespace llvm;
+
+ //
+ // Record sort by name function.
+ //
+ struct LessRecord {
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ return Rec1->getName() < Rec2->getName();
+ }
+ };
+
+ //
+ // Record sort by field "Name" function.
+ //
+ struct LessRecordFieldName {
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
+ }
+ };
+
+ //
+ // Enumeration - Emit the specified class as an enumeration.
+ //
+ void SubtargetEmitter::Enumeration(std::ostream &OS,
+ const char *ClassName,
+ bool isBits) {
+ // Get all records of class and sort
+ std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
+ sort(DefList.begin(), DefList.end(), LessRecord());
+
+ // Open enumeration
+ OS << "enum {\n";
+
+ // For each record
+ for (unsigned i = 0, N = DefList.size(); i < N;) {
+ // Next record
+ Record *Def = DefList[i];
+
+ // Get and emit name
+ std::string Name = Def->getName();
+ OS << " " << Name;
+
+ // If bit flags then emit expression (1 << i)
+ if (isBits) OS << " = " << " 1 << " << i;
+
+ // Depending on 'if more in the list' emit comma
+ if (++i < N) OS << ",";
+
+ OS << "\n";
+ }
+
+ // Close enumeration
+ OS << "};\n";
+ }
+
+ //
+ // FeatureKeyValues - Emit data of all the subtarget features. Used by command
+ // line.
+ //
+ void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
+ // Gather and sort all the features
+ std::vector<Record*> FeatureList =
+ Records.getAllDerivedDefinitions("SubtargetFeature");
+ sort(FeatureList.begin(), FeatureList.end(), LessRecord());
+
+ // Begin feature table
+ OS << "// Sorted (by key) array of values for CPU features.\n"
+ << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
+
+ // For each feature
+ for (unsigned i = 0, N = FeatureList.size(); i < N;) {
+ // Next feature
+ Record *Feature = FeatureList[i];
+
+ std::string Name = Feature->getName();
+ std::string CommandLineName = Feature->getValueAsString("Name");
+ std::string Desc = Feature->getValueAsString("Desc");
+
+ // Emit as { "feature", "decription", feactureEnum }
+ OS << " { "
+ << "\"" << CommandLineName << "\", "
+ << "\"" << Desc << "\", "
+ << Name
+ << " }";
+
+ // Depending on 'if more in the list' emit comma
+ if (++i < N) OS << ",";
+
+ OS << "\n";
+ }
+
+ // End feature table
+ OS << "};\n";
+
+ // Emit size of table
+ OS<<"\nenum {\n";
+ OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+ OS<<"};\n";
+ }
+
+ //
+ // CPUKeyValues - Emit data of all the subtarget processors. Used by command
+ // line.
+ //
+ void SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
+ // Gather and sort processor information
+ std::vector<Record*> ProcessorList =
+ Records.getAllDerivedDefinitions("Processor");
+ sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+
+ // Begin processor table
+ OS << "// Sorted (by key) array of values for CPU subtype.\n"
+ << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
+
+ // For each processor
+ for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+ // Next processor
+ Record *Processor = ProcessorList[i];
+
+ std::string Name = Processor->getValueAsString("Name");
+ std::vector<Record*> FeatureList =
+ Processor->getValueAsListOfDefs("Features");
+
+ // Emit as { "cpu", "description", f1 | f2 | ... fn },
+ OS << " { "
+ << "\"" << Name << "\", "
+ << "\"Select the " << Name << " processor\", ";
+
+ if (FeatureList.empty()) {
+ OS << "0";
+ } else {
+ for (unsigned j = 0, M = FeatureList.size(); j < M;) {
+ Record *Feature = FeatureList[j];
+ std::string Name = Feature->getName();
+ OS << Name;
+ if (++j < M) OS << " | ";
+ }
+ }
+
+ OS << " }";
+
+ // Depending on 'if more in the list' emit comma
+ if (++i < N) OS << ",";
+
+ OS << "\n";
+ }
+
+ // End processor table
+ OS << "};\n";
+
+ // Emit size of table
+ OS<<"\nenum {\n";
+ OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+ OS<<"};\n";
+ }
+
+ //
+ // CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
+ // Returns itinerary class count.
+ //
+ unsigned SubtargetEmitter::CollectAllItinClasses(std::ostream &OS,
+ std::map<std::string, unsigned> &ItinClassesMap) {
+ // Gather and sort all itinerary classes
+ std::vector<Record*> ItinClassList =
+ Records.getAllDerivedDefinitions("InstrItinClass");
+ sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
+
+ // For each itinerary class
+ unsigned N = ItinClassList.size();
+ for (unsigned i = 0; i < N; i++) {
+ // Next itinerary class
+ Record *ItinClass = ItinClassList[i];
+ // Get name of itinerary class
+ std::string Name = ItinClass->getName();
+ // Assign itinerary class a unique number
+ ItinClassesMap[Name] = i;
+ }
+
+ // Emit size of table
+ OS<<"\nenum {\n";
+ OS<<" ItinClassesSize = " << N << "\n";
+ OS<<"};\n";
+
+ // Return itinerary class count
+ return N;
+ }
+
+ //
+ // FormItineraryString - Compose a string containing the data initialization
+ // for the specified itinerary. N is the number of stages.
+ //
+ void SubtargetEmitter::FormItineraryString(Record *ItinData,
+ std::string &ItinString,
+ unsigned &NStages) {
+ // Get states list
+ std::vector<Record*> StageList = ItinData->getValueAsListOfDefs("Stages");
+
+ // For each stage
+ unsigned N = NStages = StageList.size();
+ for (unsigned i = 0; i < N; i++) {
+ // Next stage
+ Record *Stage = StageList[i];
+
+ // Form string as ,{ cycles, u1 | u2 | ... | un }
+ int Cycles = Stage->getValueAsInt("Cycles");
+ ItinString += " { " + itostr(Cycles) + ", ";
+
+ // Get unit list
+ std::vector<Record*> UnitList = Stage->getValueAsListOfDefs("Units");
+
+ // For each unit
+ for (unsigned j = 0, M = UnitList.size(); j < M;) {
+ // Next unit
+ Record *Unit = UnitList[j];
+
+ // Add name and bitwise or
+ ItinString += Unit->getName();
+ if (++j < M) ItinString += " | ";
+ }
+
+ // Close off stage
+ ItinString += " }";
+ }
+ }
+
+ //
+ // EmitStageData - Generate unique itinerary stages. Record itineraries for
+ // processors.
+ //
+ void SubtargetEmitter::EmitStageData(std::ostream &OS,
+ unsigned NItinClasses,
+ std::map<std::string, unsigned> &ItinClassesMap,
+ std::vector<std::vector<InstrItinerary> > &ProcList) {
+ // Gather processor iteraries
+ std::vector<Record*> ProcItinList =
+ Records.getAllDerivedDefinitions("ProcessorItineraries");
+
+ // If just no itinerary then don't bother
+ if (ProcItinList.size() < 2) return;
+
+ // Begin stages table
+ OS << "static llvm::InstrStage Stages[] = {\n"
+ " { 0, 0 }, // No itinerary\n";
+
+ unsigned ItinEnum = 1;
+ std::map<std::string, unsigned> ItinMap;
+ for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
+ // Next record
+ Record *Proc = ProcItinList[i];
+
+ // Get processor itinerary name
+ std::string Name = Proc->getName();
+
+ // Skip default
+ if (Name == "NoItineraries") continue;
+
+ // Create and expand processor itinerary to cover all itinerary classes
+ std::vector<InstrItinerary> ItinList;
+ ItinList.resize(NItinClasses);
+
+ // Get itinerary data list
+ std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
+
+ // For each itinerary data
+ for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
+ // Next itinerary data
+ Record *ItinData = ItinDataList[j];
+
+ // Get string and stage count
+ std::string ItinString;
+ unsigned NStages;
+ FormItineraryString(ItinData, ItinString, NStages);
+
+ // Check to see if it already exists
+ unsigned Find = ItinMap[ItinString];
+
+ // If new itinerary
+ if (Find == 0) {
+ // Emit as { cycles, u1 | u2 | ... | un }, // index
+ OS << ItinString << ", // " << ItinEnum << "\n";
+ // Record Itin class number
+ ItinMap[ItinString] = Find = ItinEnum++;
+ }
+
+ // Set up itinerary as location and location + stage count
+ InstrItinerary Intinerary = { Find, Find + NStages };
+
+ // Locate where to inject into processor itinerary table
+ std::string Name = ItinData->getValueAsDef("TheClass")->getName();
+ Find = ItinClassesMap[Name];
+
+ // Inject - empty slots will be 0, 0
+ ItinList[Find] = Intinerary;
+ }
+
+ // Add process itinerary to list
+ ProcList.push_back(ItinList);
+ }
+
+ // Closing stage
+ OS << " { 0, 0 } // End itinerary\n";
+ // End stages table
+ OS << "};\n";
+
+ // Emit size of table
+ OS<<"\nenum {\n";
+ OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n";
+ OS<<"};\n";
+ }
+
+ //
+ // EmitProcessorData - Generate data for processor itineraries.
+ //
+ void SubtargetEmitter::EmitProcessorData(std::ostream &OS,
+ std::vector<std::vector<InstrItinerary> > &ProcList) {
+ // Get an iterator for processor itinerary stages
+ std::vector<std::vector<InstrItinerary> >::iterator
+ ProcListIter = ProcList.begin();
+
+ // For each processor itinerary
+ std::vector<Record*> Itins =
+ Records.getAllDerivedDefinitions("ProcessorItineraries");
+ for (unsigned i = 0, N = Itins.size(); i < N; i++) {
+ // Next record
+ Record *Itin = Itins[i];
+
+ // Get processor itinerary name
+ std::string Name = Itin->getName();
+
+ // Skip default
+ if (Name == "NoItineraries") continue;
+
+ // Begin processor itinerary table
+ OS << "\n";
+ OS << "static llvm::InstrItinerary " << Name << "[] = {\n";
+
+ // For each itinerary class
+ std::vector<InstrItinerary> &ItinList = *ProcListIter++;
+ unsigned ItinIndex = 0;
+ for (unsigned j = 0, M = ItinList.size(); j < M;) {
+ InstrItinerary &Intinerary = ItinList[j];
+
+ // Emit in the form of { first, last } // index
+ if (Intinerary.First == 0) {
+ OS << " { 0, 0 }";
+ } else {
+ OS << " { " << Intinerary.First << ", " << Intinerary.Last << " }";
+ }
+
+ // If more in list add comma
+ if (++j < M) OS << ",";
+
+ OS << " // " << (j - 1) << "\n";
+ }
+
+ // End processor itinerary table
+ OS << "};\n";
+ }
+
+ OS << "\n";
+ OS << "static llvm::InstrItinerary NoItineraries[] = {};\n";
+ }
+
+ //
+ // EmitProcessorLookup - generate cpu name to itinerary lookup table.
+ //
+ void SubtargetEmitter::EmitProcessorLookup(std::ostream &OS) {
+ // Gather and sort processor information
+ std::vector<Record*> ProcessorList =
+ Records.getAllDerivedDefinitions("Processor");
+ sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+
+ // Begin processor table
+ OS << "\n";
+ OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
+ << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
+
+ // For each processor
+ for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+ // Next processor
+ Record *Processor = ProcessorList[i];
+
+ std::string Name = Processor->getValueAsString("Name");
+ std::string ProcItin = Processor->getValueAsDef("ProcItin")->getName();
+
+ // Emit as { "cpu", procinit },
+ OS << " { "
+ << "\"" << Name << "\", "
+ << "(void *)&" << ProcItin;
+
+ OS << " }";
+
+ // Depending on ''if more in the list'' emit comma
+ if (++i < N) OS << ",";
+
+ OS << "\n";
+ }
+
+ // End processor table
+ OS << "};\n";
+
+ // Emit size of table
+ OS<<"\nenum {\n";
+ OS<<" ProcItinKVSize = sizeof(ProcItinKV)/"
+ "sizeof(llvm::SubtargetInfoKV)\n";
+ OS<<"};\n";
+ }
+
+ //
+ // EmitData - Emits all stages and itineries, folding common patterns.
+ //
+ void SubtargetEmitter::EmitData(std::ostream &OS) {
+ std::map<std::string, unsigned> ItinClassesMap;
+ std::vector<std::vector<InstrItinerary> > ProcList;
+
+ // Enumerate all the itinerary classes
+ unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
+ // Make sure the rest is worth the effort
+ HasItineraries = NItinClasses != 0;
+
+ if (HasItineraries) {
+ // Emit the stage data
+ EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList);
+ // Emit the processor itinerary data
+ EmitProcessorData(OS, ProcList);
+ // Emit the processor lookup data
+ EmitProcessorLookup(OS);
+ }
+ }
+
+ //
+ // ParseFeaturesFunction - Produces a subtarget specific function for parsing
+ // the subtarget features string.
+ //
+ void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
+ std::vector<Record*> Features =
+ Records.getAllDerivedDefinitions("SubtargetFeature");
+ sort(Features.begin(), Features.end(), LessRecord());
+
+ OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
+ "// subtarget options.\n"
+ "void llvm::";
+ OS << Target;
+ OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
+ " const std::string &CPU) {\n"
+ " SubtargetFeatures Features(FS);\n"
+ " Features.setCPUIfNone(CPU);\n"
+ " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
+ " FeatureKV, FeatureKVSize);\n";
+
+ for (unsigned i = 0; i < Features.size(); i++) {
+ // Next record
+ Record *R = Features[i];
+ std::string Instance = R->getName();
+ std::string Name = R->getValueAsString("Name");
+ std::string Type = R->getValueAsString("Type");
+ std::string Attribute = R->getValueAsString("Attribute");
+
+ OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
+ }
+
+ if (HasItineraries) {
+ OS << "\n"
+ << " InstrItinerary *Itinerary = (InstrItinerary *)"
+ "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
+ " InstrItins = InstrItineraryData(Stages, Itinerary);\n";
+ }
+
+ OS << "}\n";
+ }
+
+ //
+ // SubtargetEmitter::run - Main subtarget enumeration emitter.
+ //
+ void SubtargetEmitter::run(std::ostream &OS) {
+ Target = CodeGenTarget().getName();
+
+ EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
+
+ OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
+ OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
+
+ Enumeration(OS, "FuncUnit", true);
+ OS<<"\n";
+ // Enumeration(OS, "InstrItinClass", false);
+ // OS<<"\n";
+ Enumeration(OS, "SubtargetFeature", true);
+ OS<<"\n";
+ FeatureKeyValues(OS);
+ OS<<"\n";
+ CPUKeyValues(OS);
+ OS<<"\n";
+ EmitData(OS);
+ OS<<"\n";
+ ParseFeaturesFunction(OS);
+ }
Index: llvm/utils/TableGen/SubtargetEmitter.h
diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.h:1.7.2.2
*** /dev/null Wed Nov 16 12:33:56 2005
--- llvm/utils/TableGen/SubtargetEmitter.h Wed Nov 16 12:33:45 2005
***************
*** 0 ****
--- 1,62 ----
+ //===- SubtargetEmitter.h - Generate subtarget enumerations -----*- C++ -*-===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by James M. Laskey and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This tablegen backend emits subtarget enumerations.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef SUBTARGET_EMITTER_H
+ #define SUBTARGET_EMITTER_H
+
+ #include "TableGenBackend.h"
+ #include "llvm/Target/TargetInstrItineraries.h"
+ #include <vector>
+ #include <map>
+ #include <string>
+
+
+ namespace llvm {
+
+ class SubtargetEmitter : public TableGenBackend {
+
+ RecordKeeper &Records;
+ std::string Target;
+ bool HasItineraries;
+
+ void Enumeration(std::ostream &OS, const char *ClassName, bool isBits);
+ void FeatureKeyValues(std::ostream &OS);
+ void CPUKeyValues(std::ostream &OS);
+ unsigned CollectAllItinClasses(std::ostream &OS,
+ std::map<std::string, unsigned> &ItinClassesMap);
+ void FormItineraryString(Record *ItinData, std::string &ItinString,
+ unsigned &NStages);
+ void EmitStageData(std::ostream &OS, unsigned NItinClasses,
+ std::map<std::string, unsigned> &ItinClassesMap,
+ std::vector<std::vector<InstrItinerary> > &ProcList);
+ void EmitProcessorData(std::ostream &OS,
+ std::vector<std::vector<InstrItinerary> > &ProcList);
+ void EmitProcessorLookup(std::ostream &OS);
+ void EmitData(std::ostream &OS);
+ void ParseFeaturesFunction(std::ostream &OS);
+
+ public:
+ SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}
+
+ // run - Output the subtarget enumerations, returning true on failure.
+ void run(std::ostream &o);
+
+ };
+
+
+ } // End llvm namespace
+
+ #endif
+
+
+
Index: llvm/utils/TableGen/TableGen.cpp
diff -u llvm/utils/TableGen/TableGen.cpp:1.39 llvm/utils/TableGen/TableGen.cpp:1.39.2.1
--- llvm/utils/TableGen/TableGen.cpp:1.39 Fri Sep 2 20:14:03 2005
+++ llvm/utils/TableGen/TableGen.cpp Wed Nov 16 12:33:45 2005
@@ -23,8 +23,8 @@
#include "RegisterInfoEmitter.h"
#include "InstrInfoEmitter.h"
#include "AsmWriterEmitter.h"
-#include "InstrSelectorEmitter.h"
#include "DAGISelEmitter.h"
+#include "SubtargetEmitter.h"
#include <algorithm>
#include <cstdio>
#include <fstream>
@@ -34,8 +34,9 @@
PrintRecords,
GenEmitter,
GenRegisterEnums, GenRegister, GenRegisterHeader,
- GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector,
+ GenInstrEnums, GenInstrs, GenAsmWriter,
GenDAGISel,
+ GenSubtarget,
PrintEnums,
Parse
};
@@ -59,10 +60,10 @@
"Generate instruction descriptions"),
clEnumValN(GenAsmWriter, "gen-asm-writer",
"Generate assembly writer"),
- clEnumValN(GenInstrSelector, "gen-instr-selector",
- "Generate an instruction selector"),
clEnumValN(GenDAGISel, "gen-dag-isel",
"Generate a DAG instruction selector"),
+ clEnumValN(GenSubtarget, "gen-subtarget",
+ "Generate subtarget enumerations"),
clEnumValN(PrintEnums, "print-enums",
"Print enum values for a class"),
clEnumValN(Parse, "parse",
@@ -466,12 +467,12 @@
AsmWriterEmitter(Records).run(*Out);
break;
- case GenInstrSelector:
- InstrSelectorEmitter(Records).run(*Out);
- break;
case GenDAGISel:
DAGISelEmitter(Records).run(*Out);
break;
+ case GenSubtarget:
+ SubtargetEmitter(Records).run(*Out);
+ break;
case PrintEnums:
{
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
More information about the llvm-commits
mailing list