Simplify TGParser::ProcessForEachDefs.
Use static type checking. llvm-svn: 157430
This commit is contained in:
parent
79d3eecbb4
commit
8a120b10bd
|
@ -292,107 +292,78 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
|
||||||
/// ProcessForeachDefs - Given a record, apply all of the variable
|
/// ProcessForeachDefs - Given a record, apply all of the variable
|
||||||
/// values in all surrounding foreach loops, creating new records for
|
/// values in all surrounding foreach loops, creating new records for
|
||||||
/// each combination of values.
|
/// each combination of values.
|
||||||
bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
|
bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc) {
|
||||||
SMLoc Loc) {
|
if (Loops.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// We want to instantiate a new copy of CurRec for each combination
|
// We want to instantiate a new copy of CurRec for each combination
|
||||||
// of nested loop iterator values. We don't want top instantiate
|
// of nested loop iterator values. We don't want top instantiate
|
||||||
// any copies until we have values for each loop iterator.
|
// any copies until we have values for each loop iterator.
|
||||||
IterSet IterVals;
|
IterSet IterVals;
|
||||||
for (LoopVector::iterator Loop = Loops.begin(), LoopEnd = Loops.end();
|
return ProcessForeachDefs(CurRec, Loc, IterVals);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ProcessForeachDefs - Given a record, a loop and a loop iterator,
|
/// ProcessForeachDefs - Given a record, a loop and a loop iterator,
|
||||||
/// apply each of the variable values in this loop and then process
|
/// apply each of the variable values in this loop and then process
|
||||||
/// subloops.
|
/// subloops.
|
||||||
bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
|
bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
|
||||||
SMLoc Loc, IterSet &IterVals,
|
// Recursively build a tuple of iterator values.
|
||||||
ForeachLoop &CurLoop,
|
if (IterVals.size() != Loops.size()) {
|
||||||
LoopVector::iterator NextLoop) {
|
assert(IterVals.size() < Loops.size());
|
||||||
Init *IterVar = CurLoop.IterVar;
|
ForeachLoop &CurLoop = Loops[IterVals.size()];
|
||||||
ListInit *List = dynamic_cast<ListInit *>(CurLoop.ListValue);
|
ListInit *List = dynamic_cast<ListInit *>(CurLoop.ListValue);
|
||||||
|
if (List == 0) {
|
||||||
|
Error(Loc, "Loop list is not a list");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (List == 0) {
|
// Process each value.
|
||||||
Error(Loc, "Loop list is not a list");
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process each value.
|
Records.addDef(IterRec);
|
||||||
for (int64_t i = 0; i < List->getSize(); ++i) {
|
IterRec->resolveReferences();
|
||||||
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();
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1728,7 +1699,7 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
|
||||||
///
|
///
|
||||||
/// ForeachDeclaration ::= ID '=' Value
|
/// ForeachDeclaration ::= ID '=' Value
|
||||||
///
|
///
|
||||||
Init *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
|
VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
|
||||||
if (Lex.getCode() != tgtok::Id) {
|
if (Lex.getCode() != tgtok::Id) {
|
||||||
TokError("Expected identifier in foreach declaration");
|
TokError("Expected identifier in foreach declaration");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1745,15 +1716,15 @@ Init *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
|
||||||
Lex.Lex(); // Eat the '='
|
Lex.Lex(); // Eat the '='
|
||||||
|
|
||||||
// Expect a list initializer.
|
// Expect a list initializer.
|
||||||
ForeachListValue = ParseValue(0, 0, ParseForeachMode);
|
Init *List = ParseSimpleValue(0, 0, ParseForeachMode);
|
||||||
|
|
||||||
TypedInit *TypedList = dynamic_cast<TypedInit *>(ForeachListValue);
|
ForeachListValue = dynamic_cast<ListInit*>(List);
|
||||||
if (TypedList == 0) {
|
if (ForeachListValue == 0) {
|
||||||
TokError("Value list is untyped");
|
TokError("Expected a Value list");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecTy *ValueType = TypedList->getType();
|
RecTy *ValueType = ForeachListValue->getType();
|
||||||
ListRecTy *ListType = dynamic_cast<ListRecTy *>(ValueType);
|
ListRecTy *ListType = dynamic_cast<ListRecTy *>(ValueType);
|
||||||
if (ListType == 0) {
|
if (ListType == 0) {
|
||||||
TokError("Value list is not of list type");
|
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,
|
Error(DefLoc,
|
||||||
"Could not process loops for def" + CurRec->getNameInitAsString());
|
"Could not process loops for def" + CurRec->getNameInitAsString());
|
||||||
return true;
|
return true;
|
||||||
|
@ -1999,8 +1970,8 @@ bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
|
||||||
|
|
||||||
// Make a temporary object to record items associated with the for
|
// Make a temporary object to record items associated with the for
|
||||||
// loop.
|
// loop.
|
||||||
Init *ListValue = 0;
|
ListInit *ListValue = 0;
|
||||||
Init *IterName = ParseForeachDeclaration(ListValue);
|
VarInit *IterName = ParseForeachDeclaration(ListValue);
|
||||||
if (IterName == 0)
|
if (IterName == 0)
|
||||||
return TokError("expected declaration in for");
|
return TokError("expected declaration in for");
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,11 @@ namespace llvm {
|
||||||
/// ForeachLoop - Record the iteration state associated with a for loop.
|
/// ForeachLoop - Record the iteration state associated with a for loop.
|
||||||
/// This is used to instantiate items in the loop body.
|
/// This is used to instantiate items in the loop body.
|
||||||
struct ForeachLoop {
|
struct ForeachLoop {
|
||||||
Init *IterVar;
|
VarInit *IterVar;
|
||||||
Init *ListValue;
|
ListInit *ListValue;
|
||||||
|
|
||||||
ForeachLoop(Init *IVar, Init *LValue) : IterVar(IVar), ListValue(LValue) {}
|
ForeachLoop(VarInit *IVar, ListInit *LValue)
|
||||||
|
: IterVar(IVar), ListValue(LValue) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TGParser {
|
class TGParser {
|
||||||
|
@ -113,20 +114,17 @@ private: // Semantic analysis methods.
|
||||||
|
|
||||||
// IterRecord: Map an iterator name to a value.
|
// IterRecord: Map an iterator name to a value.
|
||||||
struct IterRecord {
|
struct IterRecord {
|
||||||
Init *IterVar;
|
VarInit *IterVar;
|
||||||
Init *IterValue;
|
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
|
// IterSet: The set of all iterator values at some point in the
|
||||||
// iteration space.
|
// iteration space.
|
||||||
typedef std::vector<IterRecord> IterSet;
|
typedef std::vector<IterRecord> IterSet;
|
||||||
|
|
||||||
bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
|
bool ProcessForeachDefs(Record *CurRec, SMLoc Loc);
|
||||||
SMLoc Loc);
|
bool ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals);
|
||||||
bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass,
|
|
||||||
SMLoc Loc, IterSet &IterVals, ForeachLoop &CurLoop,
|
|
||||||
LoopVector::iterator NextLoop);
|
|
||||||
|
|
||||||
private: // Parser methods.
|
private: // Parser methods.
|
||||||
bool ParseObjectList(MultiClass *MC = 0);
|
bool ParseObjectList(MultiClass *MC = 0);
|
||||||
|
@ -160,7 +158,7 @@ private: // Parser methods.
|
||||||
|
|
||||||
bool ParseTemplateArgList(Record *CurRec);
|
bool ParseTemplateArgList(Record *CurRec);
|
||||||
Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
|
Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
|
||||||
Init *ParseForeachDeclaration(Init *&ForeachListValue);
|
VarInit *ParseForeachDeclaration(ListInit *&ForeachListValue);
|
||||||
|
|
||||||
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
|
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
|
||||||
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
|
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
|
||||||
|
|
Loading…
Reference in New Issue