本文整理汇总了C++中DagInit::getOperator方法的典型用法代码示例。如果您正苦于以下问题:C++ DagInit::getOperator方法的具体用法?C++ DagInit::getOperator怎么用?C++ DagInit::getOperator使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DagInit
的用法示例。
在下文中一共展示了DagInit::getOperator方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: evaluate
void SetTheory::evaluate(Init *Expr, RecSet &Elts) {
// A def in a list can be a just an element, or it may expand.
if (DefInit *Def = dynamic_cast<DefInit*>(Expr)) {
if (const RecVec *Result = expand(Def->getDef()))
return Elts.insert(Result->begin(), Result->end());
Elts.insert(Def->getDef());
return;
}
// Lists simply expand.
if (ListInit *LI = dynamic_cast<ListInit*>(Expr))
return evaluate(LI->begin(), LI->end(), Elts);
// Anything else must be a DAG.
DagInit *DagExpr = dynamic_cast<DagInit*>(Expr);
if (!DagExpr)
throw "Invalid set element: " + Expr->getAsString();
DefInit *OpInit = dynamic_cast<DefInit*>(DagExpr->getOperator());
if (!OpInit)
throw "Bad set expression: " + Expr->getAsString();
Operator *Op = Operators.lookup(OpInit->getDef()->getName());
if (!Op)
throw "Unknown set operator: " + Expr->getAsString();
Op->apply(*this, DagExpr, Elts);
}
示例2: evaluate
void SetTheory::evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc) {
// A def in a list can be a just an element, or it may expand.
if (DefInit *Def = dyn_cast<DefInit>(Expr)) {
if (const RecVec *Result = expand(Def->getDef()))
return Elts.insert(Result->begin(), Result->end());
Elts.insert(Def->getDef());
return;
}
// Lists simply expand.
if (ListInit *LI = dyn_cast<ListInit>(Expr))
return evaluate(LI->begin(), LI->end(), Elts, Loc);
// Anything else must be a DAG.
DagInit *DagExpr = dyn_cast<DagInit>(Expr);
if (!DagExpr)
PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString());
DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator());
if (!OpInit)
PrintFatalError(Loc, "Bad set expression: " + Expr->getAsString());
auto I = Operators.find(OpInit->getDef()->getName());
if (I == Operators.end())
PrintFatalError(Loc, "Unknown set operator: " + Expr->getAsString());
I->second->apply(*this, DagExpr, Elts, Loc);
}
示例3: TheDef
CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
: TheDef(R), AsmString(AsmStr) {
Name = R->getValueAsString("Name");
Namespace = R->getValueAsString("Namespace");
isReturn = R->getValueAsBit("isReturn");
isBranch = R->getValueAsBit("isBranch");
isBarrier = R->getValueAsBit("isBarrier");
isCall = R->getValueAsBit("isCall");
isLoad = R->getValueAsBit("isLoad");
isStore = R->getValueAsBit("isStore");
bool isTwoAddress = R->getValueAsBit("isTwoAddress");
isPredicated = false; // set below.
isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
isCommutable = R->getValueAsBit("isCommutable");
isTerminator = R->getValueAsBit("isTerminator");
isReMaterializable = R->getValueAsBit("isReMaterializable");
hasDelaySlot = R->getValueAsBit("hasDelaySlot");
usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
noResults = R->getValueAsBit("noResults");
hasVariableNumberOfOperands = false;
DagInit *DI;
try {
DI = R->getValueAsDag("OperandList");
} catch (...) {
// Error getting operand list, just ignore it (sparcv9).
AsmString.clear();
OperandList.clear();
return;
}
unsigned MIOperandNo = 0;
std::set<std::string> OperandNames;
for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i));
if (!Arg)
throw "Illegal operand for the '" + R->getName() + "' instruction!";
Record *Rec = Arg->getDef();
std::string PrintMethod = "printOperand";
unsigned NumOps = 1;
DagInit *MIOpInfo = 0;
if (Rec->isSubClassOf("Operand")) {
PrintMethod = Rec->getValueAsString("PrintMethod");
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
// Verify that MIOpInfo has an 'ops' root value.
if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
dynamic_cast<DefInit*>(MIOpInfo->getOperator())
->getDef()->getName() != "ops")
throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
"'\n";
// If we have MIOpInfo, then we have #operands equal to number of entries
// in MIOperandInfo.
if (unsigned NumArgs = MIOpInfo->getNumArgs())
NumOps = NumArgs;
isPredicated |= Rec->isSubClassOf("PredicateOperand");
} else if (Rec->getName() == "variable_ops") {
hasVariableNumberOfOperands = true;
continue;
} else if (!Rec->isSubClassOf("RegisterClass") &&
Rec->getName() != "ptr_rc")
throw "Unknown operand class '" + Rec->getName() +
"' in instruction '" + R->getName() + "' instruction!";
// Check that the operand has a name and that it's unique.
if (DI->getArgName(i).empty())
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
" has no name!";
if (!OperandNames.insert(DI->getArgName(i)).second)
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
" has the same name as a previous operand!";
OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod,
MIOperandNo, NumOps, MIOpInfo));
MIOperandNo += NumOps;
}
// Parse Constraints.
ParseConstraints(R->getValueAsString("Constraints"), this);
// For backward compatibility: isTwoAddress means operand 1 is tied to
// operand 0.
if (isTwoAddress) {
if (!OperandList[1].Constraints[0].empty())
throw R->getName() + ": cannot use isTwoAddress property: instruction "
"already has constraint set!";
OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))";
}
// Any operands with unset constraints get 0 as their constraint.
for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
if (OperandList[op].Constraints[j].empty())
OperandList[op].Constraints[j] = "0";
//.........这里部分代码省略.........
示例4: if
CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
isPredicable = false;
hasOptionalDef = false;
isVariadic = false;
DagInit *OutDI = R->getValueAsDag("OutOperandList");
if (DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
if (Init->getDef()->getName() != "outs")
PrintFatalError(R->getName() + ": invalid def name for output list: use 'outs'");
} else
PrintFatalError(R->getName() + ": invalid output list: use 'outs'");
NumDefs = OutDI->getNumArgs();
DagInit *InDI = R->getValueAsDag("InOperandList");
if (DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
if (Init->getDef()->getName() != "ins")
PrintFatalError(R->getName() + ": invalid def name for input list: use 'ins'");
} else
PrintFatalError(R->getName() + ": invalid input list: use 'ins'");
unsigned MIOperandNo = 0;
std::set<std::string> OperandNames;
for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i) {
Init *ArgInit;
std::string ArgName;
if (i < NumDefs) {
ArgInit = OutDI->getArg(i);
ArgName = OutDI->getArgName(i);
} else {
ArgInit = InDI->getArg(i-NumDefs);
ArgName = InDI->getArgName(i-NumDefs);
}
DefInit *Arg = dyn_cast<DefInit>(ArgInit);
if (!Arg)
PrintFatalError("Illegal operand for the '" + R->getName() + "' instruction!");
Record *Rec = Arg->getDef();
std::string PrintMethod = "printOperand";
std::string EncoderMethod;
std::string OperandType = "OPERAND_UNKNOWN";
unsigned NumOps = 1;
DagInit *MIOpInfo = nullptr;
if (Rec->isSubClassOf("RegisterOperand")) {
PrintMethod = Rec->getValueAsString("PrintMethod");
} else if (Rec->isSubClassOf("Operand")) {
PrintMethod = Rec->getValueAsString("PrintMethod");
OperandType = Rec->getValueAsString("OperandType");
// If there is an explicit encoder method, use it.
EncoderMethod = Rec->getValueAsString("EncoderMethod");
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
// Verify that MIOpInfo has an 'ops' root value.
if (!isa<DefInit>(MIOpInfo->getOperator()) ||
cast<DefInit>(MIOpInfo->getOperator())->getDef()->getName() != "ops")
PrintFatalError("Bad value for MIOperandInfo in operand '" + Rec->getName() +
"'\n");
// If we have MIOpInfo, then we have #operands equal to number of entries
// in MIOperandInfo.
if (unsigned NumArgs = MIOpInfo->getNumArgs())
NumOps = NumArgs;
if (Rec->isSubClassOf("PredicateOp"))
isPredicable = true;
else if (Rec->isSubClassOf("OptionalDefOperand"))
hasOptionalDef = true;
} else if (Rec->getName() == "variable_ops") {
isVariadic = true;
continue;
} else if (Rec->isSubClassOf("RegisterClass")) {
OperandType = "OPERAND_REGISTER";
} else if (!Rec->isSubClassOf("PointerLikeRegClass") &&
!Rec->isSubClassOf("unknown_class"))
PrintFatalError("Unknown operand class '" + Rec->getName() +
"' in '" + R->getName() + "' instruction!");
// Check that the operand has a name and that it's unique.
if (ArgName.empty())
PrintFatalError("In instruction '" + R->getName() + "', operand #" +
Twine(i) + " has no name!");
if (!OperandNames.insert(ArgName).second)
PrintFatalError("In instruction '" + R->getName() + "', operand #" +
Twine(i) + " has the same name as a previous operand!");
OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
OperandType, MIOperandNo, NumOps,
MIOpInfo));
MIOperandNo += NumOps;
}
// Make sure the constraints list for each operand is large enough to hold
// constraint info, even if none is present.
for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
OperandList[i].Constraints.resize(OperandList[i].MINumOperands);
}
示例5: inferSubRegIndices
// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion.
RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
SubRegMap &SRM = SubReg[Reg];
if (!SRM.empty())
return SRM;
std::vector<Record*> SubRegs = Reg->getValueAsListOfDefs("SubRegs");
std::vector<Record*> Indices = Reg->getValueAsListOfDefs("SubRegIndices");
if (SubRegs.size() != Indices.size())
throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs";
// First insert the direct subregs and make sure they are fully indexed.
for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second)
throw "SubRegIndex " + Indices[i]->getName()
+ " appears twice in Register " + Reg->getName();
inferSubRegIndices(SubRegs[i]);
}
// Keep track of inherited subregs and how they can be reached.
// Register -> (SubRegIndex, SubRegIndex)
typedef std::map<Record*, std::pair<Record*,Record*>, LessRecord> OrphanMap;
OrphanMap Orphans;
// Clone inherited subregs. Here the order is important - earlier subregs take
// precedence.
for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
SubRegMap &M = SubReg[SubRegs[i]];
for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si)
if (!SRM.insert(*si).second)
Orphans[si->second] = std::make_pair(Indices[i], si->first);
}
// Finally process the composites.
ListInit *Comps = Reg->getValueAsListInit("CompositeIndices");
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
if (!Pat)
throw "Invalid dag '" + Comps->getElement(i)->getAsString()
+ "' in CompositeIndices";
DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw "Invalid SubClassIndex in " + Pat->getAsString();
// Resolve list of subreg indices into R2.
Record *R2 = Reg;
for (DagInit::const_arg_iterator di = Pat->arg_begin(),
de = Pat->arg_end(); di != de; ++di) {
DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw "Invalid SubClassIndex in " + Pat->getAsString();
SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef());
if (ni == SubReg[R2].end())
throw "Composite " + Pat->getAsString() + " refers to bad index in "
+ R2->getName();
R2 = ni->second;
}
// Insert composite index. Allow overriding inherited indices etc.
SRM[BaseIdxInit->getDef()] = R2;
// R2 is now directly addressable, no longer an orphan.
Orphans.erase(R2);
}
// Now, Orphans contains the inherited subregisters without a direct index.
if (!Orphans.empty()) {
errs() << "Error: Register " << getQualifiedName(Reg)
<< " inherited subregisters without an index:\n";
for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e;
++i) {
errs() << " " << getQualifiedName(i->first)
<< " = " << i->second.first->getName()
<< ", " << i->second.second->getName() << "\n";
}
abort();
}
return SRM;
}
示例6: if
CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
: TheDef(R), AsmString(AsmStr) {
Namespace = R->getValueAsString("Namespace");
isReturn = R->getValueAsBit("isReturn");
isBranch = R->getValueAsBit("isBranch");
isIndirectBranch = R->getValueAsBit("isIndirectBranch");
isBarrier = R->getValueAsBit("isBarrier");
isCall = R->getValueAsBit("isCall");
canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
mayLoad = R->getValueAsBit("mayLoad");
mayStore = R->getValueAsBit("mayStore");
bool isTwoAddress = R->getValueAsBit("isTwoAddress");
isPredicable = R->getValueAsBit("isPredicable");
isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
isCommutable = R->getValueAsBit("isCommutable");
isTerminator = R->getValueAsBit("isTerminator");
isReMaterializable = R->getValueAsBit("isReMaterializable");
hasDelaySlot = R->getValueAsBit("hasDelaySlot");
usesCustomInserter = R->getValueAsBit("usesCustomInserter");
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
hasSideEffects = R->getValueAsBit("hasSideEffects");
neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
hasOptionalDef = false;
isVariadic = false;
ImplicitDefs = R->getValueAsListOfDefs("Defs");
ImplicitUses = R->getValueAsListOfDefs("Uses");
if (neverHasSideEffects + hasSideEffects > 1)
throw R->getName() + ": multiple conflicting side-effect flags set!";
DagInit *OutDI = R->getValueAsDag("OutOperandList");
if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) {
if (Init->getDef()->getName() != "outs")
throw R->getName() + ": invalid def name for output list: use 'outs'";
} else
throw R->getName() + ": invalid output list: use 'outs'";
NumDefs = OutDI->getNumArgs();
DagInit *InDI = R->getValueAsDag("InOperandList");
if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) {
if (Init->getDef()->getName() != "ins")
throw R->getName() + ": invalid def name for input list: use 'ins'";
} else
throw R->getName() + ": invalid input list: use 'ins'";
unsigned MIOperandNo = 0;
std::set<std::string> OperandNames;
for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
Init *ArgInit;
std::string ArgName;
if (i < NumDefs) {
ArgInit = OutDI->getArg(i);
ArgName = OutDI->getArgName(i);
} else {
ArgInit = InDI->getArg(i-NumDefs);
ArgName = InDI->getArgName(i-NumDefs);
}
DefInit *Arg = dynamic_cast<DefInit*>(ArgInit);
if (!Arg)
throw "Illegal operand for the '" + R->getName() + "' instruction!";
Record *Rec = Arg->getDef();
std::string PrintMethod = "printOperand";
unsigned NumOps = 1;
DagInit *MIOpInfo = 0;
if (Rec->isSubClassOf("Operand")) {
PrintMethod = Rec->getValueAsString("PrintMethod");
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
// Verify that MIOpInfo has an 'ops' root value.
if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
dynamic_cast<DefInit*>(MIOpInfo->getOperator())
->getDef()->getName() != "ops")
throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
"'\n";
// If we have MIOpInfo, then we have #operands equal to number of entries
// in MIOperandInfo.
if (unsigned NumArgs = MIOpInfo->getNumArgs())
NumOps = NumArgs;
if (Rec->isSubClassOf("PredicateOperand"))
isPredicable = true;
else if (Rec->isSubClassOf("OptionalDefOperand"))
hasOptionalDef = true;
} else if (Rec->getName() == "variable_ops") {
isVariadic = true;
continue;
} else if (!Rec->isSubClassOf("RegisterClass") &&
Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
throw "Unknown operand class '" + Rec->getName() +
"' in '" + R->getName() + "' instruction!";
//.........这里部分代码省略.........
示例7: TGError
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
if (SubRegsComplete)
return SubRegs;
SubRegsComplete = true;
std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
if (SubList.size() != Indices.size())
throw TGError(TheDef->getLoc(), "Register " + getName() +
" SubRegIndices doesn't match SubRegs");
// First insert the direct subregs and make sure they are fully indexed.
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second)
throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() +
" appears twice in Register " + getName());
}
// Keep track of inherited subregs and how they can be reached.
SmallVector<Orphan, 8> Orphans;
// Clone inherited subregs and place duplicate entries on Orphans.
// Here the order is important - earlier subregs take precedence.
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Add this as a super-register of SR now all sub-registers are in the list.
// This creates a topological ordering, the exact order depends on the
// order getSubRegs is called on all registers.
SR->SuperRegs.push_back(this);
for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
++SI) {
if (!SubRegs.insert(*SI).second)
Orphans.push_back(Orphan(SI->second, Indices[i], SI->first));
// Noop sub-register indexes are possible, so avoid duplicates.
if (SI->second != SR)
SI->second->SuperRegs.push_back(this);
}
}
// Process the composites.
ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
if (!Pat)
throw TGError(TheDef->getLoc(), "Invalid dag '" +
Comps->getElement(i)->getAsString() +
"' in CompositeIndices");
DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
// Resolve list of subreg indices into R2.
CodeGenRegister *R2 = this;
for (DagInit::const_arg_iterator di = Pat->arg_begin(),
de = Pat->arg_end(); di != de; ++di) {
DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef());
if (ni == R2Subs.end())
throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
" refers to bad index in " + R2->getName());
R2 = ni->second;
}
// Insert composite index. Allow overriding inherited indices etc.
SubRegs[BaseIdxInit->getDef()] = R2;
// R2 is no longer an orphan.
for (unsigned j = 0, je = Orphans.size(); j != je; ++j)
if (Orphans[j].SubReg == R2)
Orphans[j].SubReg = 0;
}
// Now Orphans contains the inherited subregisters without a direct index.
// Create inferred indexes for all missing entries.
for (unsigned i = 0, e = Orphans.size(); i != e; ++i) {
Orphan &O = Orphans[i];
if (!O.SubReg)
continue;
SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] =
O.SubReg;
}
return SubRegs;
}
示例8: ParseTreePattern
InvTreePatternNode *InvTreePattern::ParseTreePattern(Init *TheInit, StringRef OpName) {
if (DefInit *DI = dyn_cast<DefInit>(TheInit)) {
Record *R = DI->getDef();
// On direct reference to a leaf DagNode (SDNode) or a pattern fragment, create
// a new InvTreePatternNode.
if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
return ParseTreePattern(DagInit::get(DI, "",
std::vector<std::pair<Init*, std::string> >()), OpName);
}
// Treat as an input element
InvTreePatternNode *Res = new InvTreePatternNode(DI);
if (R->getName() == "node" && OpName.empty()) {
error("'node' requires an opname to match operand lists!");
}
Res->setName(OpName);
return Res;
}
if (IntInit *II = dyn_cast<IntInit>(TheInit)) {
if (!OpName.empty()) {
error("Constant int args should not have a name!");
}
return new InvTreePatternNode(II);
}
if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) {
// Convert to IntInit
Init *II = BI->convertInitializerTo(IntRecTy::get());
if (II == 0 || !isa<IntInit>(II)) {
error("Bits values must be integer constants!");
}
return ParseTreePattern(II, OpName);
}
DagInit *Dag = dyn_cast<DagInit>(TheInit);
if (!Dag) {
TheInit->dump();
error("The Pattern has an unexpected init type.");
}
DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
if (!OpDef) {
error("Thye Pattern has an unexpected operator type.");
}
Record *OpRec = OpDef->getDef();
if (OpRec->isSubClassOf("ValueType")) {
// ValueType is the type of a leaf node.
if (Dag->getNumArgs() != 1) {
error("Expected 1 argument for a ValueType operator.");
}
InvTreePatternNode *New = ParseTreePattern(Dag->getArg(0), Dag->getArgName(0));
// assert(New->getNumTypes() == 1 && "Unable to handle multiple types!");
// New->UpdateNodeType(0, getValueType(OpRec), *this);
if (!OpName.empty()) {
error("ValueType should not have a name!");
}
return New;
}
// Verify that this makes sense for an operator
if (!OpRec->isSubClassOf("PatFrag") && !OpRec->isSubClassOf("SDNode") &&
!OpRec->isSubClassOf("Instruction") && !OpRec->isSubClassOf("SDNodeXForm") &&
!OpRec->isSubClassOf("Intrinsic") && OpRec->getName() != "set" &&
OpRec->getName() != "implicit" && OpRec->getName() != "outs" &&
OpRec->getName() != "ins" && OpRec->getName() != "null_frag") {
error("Unrecognized node '" + OpRec->getName() + "'!");
}
// Unlike Regular treepatterns, we assume all patterns are "input" patterns
// in the TableGen context
if (OpRec->isSubClassOf("Instruction") ||
OpRec->isSubClassOf("SDNodeXForm")) {
error("Cannot use '" + OpRec->getName() + "' in the output pattern.");
}
std::vector<InvTreePatternNode*> Children;
// Parse operands
for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgName(i)));
}
if (OpRec->isSubClassOf("Intrinsic")) {
// Unhandled...
DEBUG(error("Intrinsics unhandled at this time."););
示例9: TGError
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
if (SubRegsComplete)
return SubRegs;
SubRegsComplete = true;
std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
if (SubList.size() != IdxList.size())
throw TGError(TheDef->getLoc(), "Register " + getName() +
" SubRegIndices doesn't match SubRegs");
// First insert the direct subregs and make sure they are fully indexed.
SmallVector<CodeGenSubRegIndex*, 8> Indices;
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
Indices.push_back(Idx);
if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
" appears twice in Register " + getName());
}
// Keep track of inherited subregs and how they can be reached.
SmallPtrSet<CodeGenRegister*, 8> Orphans;
// Clone inherited subregs and place duplicate entries in Orphans.
// Here the order is important - earlier subregs take precedence.
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Add this as a super-register of SR now all sub-registers are in the list.
// This creates a topological ordering, the exact order depends on the
// order getSubRegs is called on all registers.
SR->SuperRegs.push_back(this);
for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
++SI) {
if (!SubRegs.insert(*SI).second)
Orphans.insert(SI->second);
// Noop sub-register indexes are possible, so avoid duplicates.
if (SI->second != SR)
SI->second->SuperRegs.push_back(this);
}
}
// Expand any composed subreg indices.
// If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
// qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process
// expanded subreg indices recursively.
for (unsigned i = 0; i != Indices.size(); ++i) {
CodeGenSubRegIndex *Idx = Indices[i];
const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
CodeGenRegister *SR = SubRegs[Idx];
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Look at the possible compositions of Idx.
// They may not all be supported by SR.
for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
E = Comps.end(); I != E; ++I) {
SubRegMap::const_iterator SRI = Map.find(I->first);
if (SRI == Map.end())
continue; // Idx + I->first doesn't exist in SR.
// Add I->second as a name for the subreg SRI->second, assuming it is
// orphaned, and the name isn't already used for something else.
if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
continue;
// We found a new name for the orphaned sub-register.
SubRegs.insert(std::make_pair(I->second, SRI->second));
Indices.push_back(I->second);
}
}
// Process the composites.
ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
if (!Pat)
throw TGError(TheDef->getLoc(), "Invalid dag '" +
Comps->getElement(i)->getAsString() +
"' in CompositeIndices");
DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());
// Resolve list of subreg indices into R2.
CodeGenRegister *R2 = this;
for (DagInit::const_arg_iterator di = Pat->arg_begin(),
de = Pat->arg_end(); di != de; ++di) {
DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
//.........这里部分代码省略.........