Simplify TGParser::ProcessForEachDefs.

Use static type checking.

llvm-svn: 157430
This commit is contained in:
Jakob Stoklund Olesen 2012-05-24 22:17:33 +00:00
parent 79d3eecbb4
commit 8a120b10bd
2 changed files with 77 additions and 108 deletions

View File

@ -292,107 +292,78 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
/// ProcessForeachDefs - Given a record, apply all of the variable
/// values in all surrounding foreach loops, creating new records for
/// each combination of values.
bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
SMLoc Loc) {
bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc) {
if (Loops.empty())
return false;
// We want to instantiate a new copy of CurRec for each combination
// of nested loop iterator values. We don't want top instantiate
// any copies until we have values for each loop iterator.
IterSet IterVals;
for (LoopVector::iterator Loop = Loops.begin(), LoopEnd = Loops.end();
Loop != LoopEnd;
++Loop) {
// Process this loop.
if (ProcessForeachDefs(CurRec, CurMultiClass, Loc,
IterVals, *Loop, Loop+1)) {
Error(Loc,
"Could not process loops for def " + CurRec->getNameInitAsString());
return true;
}
}
return false;
return ProcessForeachDefs(CurRec, Loc, IterVals);
}
/// ProcessForeachDefs - Given a record, a loop and a loop iterator,
/// apply each of the variable values in this loop and then process
/// subloops.
bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
SMLoc Loc, IterSet &IterVals,
ForeachLoop &CurLoop,
LoopVector::iterator NextLoop) {
Init *IterVar = CurLoop.IterVar;
ListInit *List = dynamic_cast<ListInit *>(CurLoop.ListValue);
bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
// Recursively build a tuple of iterator values.
if (IterVals.size() != Loops.size()) {
assert(IterVals.size() < Loops.size());
ForeachLoop &CurLoop = Loops[IterVals.size()];
ListInit *List = dynamic_cast<ListInit *>(CurLoop.ListValue);
if (List == 0) {
Error(Loc, "Loop list is not a list");
return true;
}
if (List == 0) {
Error(Loc, "Loop list is not a list");
// Process each value.
for (int64_t i = 0; i < List->getSize(); ++i) {
Init *ItemVal = List->resolveListElementReference(*CurRec, 0, i);
IterVals.push_back(IterRecord(CurLoop.IterVar, ItemVal));
if (ProcessForeachDefs(CurRec, Loc, IterVals))
return true;
IterVals.pop_back();
}
return false;
}
// This is the bottom of the recursion. We have all of the iterator values
// for this point in the iteration space. Instantiate a new record to
// reflect this combination of values.
Record *IterRec = new Record(*CurRec);
// Set the iterator values now.
for (unsigned i = 0, e = IterVals.size(); i != e; ++i) {
VarInit *IterVar = IterVals[i].IterVar;
TypedInit *IVal = dynamic_cast<TypedInit *>(IterVals[i].IterValue);
if (IVal == 0) {
Error(Loc, "foreach iterator value is untyped");
return true;
}
IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false));
if (SetValue(IterRec, Loc, IterVar->getName(),
std::vector<unsigned>(), IVal)) {
Error(Loc, "when instantiating this def");
return true;
}
// Resolve it next.
IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName()));
// Remove it.
IterRec->removeValue(IterVar->getName());
}
if (Records.getDef(IterRec->getNameInitAsString())) {
Error(Loc, "def already exists: " + IterRec->getNameInitAsString());
return true;
}
// Process each value.
for (int64_t i = 0; i < List->getSize(); ++i) {
Init *ItemVal = List->resolveListElementReference(*CurRec, 0, i);
IterVals.push_back(IterRecord(IterVar, ItemVal));
if (IterVals.size() == Loops.size()) {
// Ok, we have all of the iterator values for this point in the
// iteration space. Instantiate a new record to reflect this
// combination of values.
Record *IterRec = new Record(*CurRec);
// Set the iterator values now.
for (IterSet::iterator i = IterVals.begin(), iend = IterVals.end();
i != iend;
++i) {
VarInit *IterVar = dynamic_cast<VarInit *>(i->IterVar);
if (IterVar == 0) {
Error(Loc, "foreach iterator is unresolved");
return true;
}
TypedInit *IVal = dynamic_cast<TypedInit *>(i->IterValue);
if (IVal == 0) {
Error(Loc, "foreach iterator value is untyped");
return true;
}
IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false));
if (SetValue(IterRec, Loc, IterVar->getName(),
std::vector<unsigned>(), IVal)) {
Error(Loc, "when instantiating this def");
return true;
}
// Resolve it next.
IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName()));
// Remove it.
IterRec->removeValue(IterVar->getName());
}
if (Records.getDef(IterRec->getNameInitAsString())) {
Error(Loc, "def already exists: " + IterRec->getNameInitAsString());
return true;
}
Records.addDef(IterRec);
IterRec->resolveReferences();
}
if (NextLoop != Loops.end()) {
// Process nested loops.
if (ProcessForeachDefs(CurRec, CurMultiClass, Loc, IterVals, *NextLoop,
NextLoop+1)) {
Error(Loc,
"Could not process loops for def " +
CurRec->getNameInitAsString());
return true;
}
}
// We're done with this iterator.
IterVals.pop_back();
}
Records.addDef(IterRec);
IterRec->resolveReferences();
return false;
}
@ -1728,7 +1699,7 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
///
/// ForeachDeclaration ::= ID '=' Value
///
Init *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
if (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in foreach declaration");
return 0;
@ -1745,15 +1716,15 @@ Init *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
Lex.Lex(); // Eat the '='
// Expect a list initializer.
ForeachListValue = ParseValue(0, 0, ParseForeachMode);
Init *List = ParseSimpleValue(0, 0, ParseForeachMode);
TypedInit *TypedList = dynamic_cast<TypedInit *>(ForeachListValue);
if (TypedList == 0) {
TokError("Value list is untyped");
ForeachListValue = dynamic_cast<ListInit*>(List);
if (ForeachListValue == 0) {
TokError("Expected a Value list");
return 0;
}
RecTy *ValueType = TypedList->getType();
RecTy *ValueType = ForeachListValue->getType();
ListRecTy *ListType = dynamic_cast<ListRecTy *>(ValueType);
if (ListType == 0) {
TokError("Value list is not of list type");
@ -1978,7 +1949,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
}
}
if (ProcessForeachDefs(CurRec, CurMultiClass, DefLoc)) {
if (ProcessForeachDefs(CurRec, DefLoc)) {
Error(DefLoc,
"Could not process loops for def" + CurRec->getNameInitAsString());
return true;
@ -1999,8 +1970,8 @@ bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
// Make a temporary object to record items associated with the for
// loop.
Init *ListValue = 0;
Init *IterName = ParseForeachDeclaration(ListValue);
ListInit *ListValue = 0;
VarInit *IterName = ParseForeachDeclaration(ListValue);
if (IterName == 0)
return TokError("expected declaration in for");

View File

@ -45,10 +45,11 @@ namespace llvm {
/// ForeachLoop - Record the iteration state associated with a for loop.
/// This is used to instantiate items in the loop body.
struct ForeachLoop {
Init *IterVar;
Init *ListValue;
VarInit *IterVar;
ListInit *ListValue;
ForeachLoop(Init *IVar, Init *LValue) : IterVar(IVar), ListValue(LValue) {}
ForeachLoop(VarInit *IVar, ListInit *LValue)
: IterVar(IVar), ListValue(LValue) {}
};
class TGParser {
@ -113,20 +114,17 @@ private: // Semantic analysis methods.
// IterRecord: Map an iterator name to a value.
struct IterRecord {
Init *IterVar;
VarInit *IterVar;
Init *IterValue;
IterRecord(Init *Var, Init *Val) : IterVar(Var), IterValue(Val) {}
IterRecord(VarInit *Var, Init *Val) : IterVar(Var), IterValue(Val) {}
};
// IterSet: The set of all iterator values at some point in the
// iteration space.
typedef std::vector<IterRecord> IterSet;
bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
SMLoc Loc);
bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
SMLoc Loc, IterSet &IterVals, ForeachLoop &CurLoop,
LoopVector::iterator NextLoop);
bool ProcessForeachDefs(Record *CurRec, SMLoc Loc);
bool ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals);
private: // Parser methods.
bool ParseObjectList(MultiClass *MC = 0);
@ -160,7 +158,7 @@ private: // Parser methods.
bool ParseTemplateArgList(Record *CurRec);
Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
Init *ParseForeachDeclaration(Init *&ForeachListValue);
VarInit *ParseForeachDeclaration(ListInit *&ForeachListValue);
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);