Refactor buildXrefs, parallel versions of ConsistencyCheck

This commit is contained in:
caheckman 2019-09-20 09:07:56 -04:00
parent 0ed1540e3a
commit efb6148b6c
9 changed files with 79 additions and 118 deletions

View file

@ -28,13 +28,12 @@ SleighBase::SleighBase(void)
/// Assuming the symbol table is populated, iterate through the table collecting
/// registers (for the map), user-op names, and context fields.
void SleighBase::buildXrefs(void)
void SleighBase::buildXrefs(vector<string> &errorPairs)
{
SymbolScope *glb = symtab.getGlobalScope();
SymbolTree::const_iterator iter;
SleighSymbol *sym;
int4 errors = 0;
ostringstream s;
for(iter=glb->begin();iter!=glb->end();++iter) {
@ -43,9 +42,8 @@ void SleighBase::buildXrefs(void)
pair<VarnodeData,string> ins(((VarnodeSymbol *)sym)->getFixedVarnode(),sym->getName());
pair<map<VarnodeData,string>::iterator,bool> res = varnode_xref.insert(ins);
if (!res.second) {
s << "Duplicate (offset,size) pair for registers: ";
s << sym->getName() << " and " << (*(res.first)).second << '\n';
errors += 1;
errorPairs.push_back(sym->getName());
errorPairs.push_back((*(res.first)).second);
}
}
else if (sym->getType() == SleighSymbol::userop_symbol) {
@ -62,8 +60,6 @@ void SleighBase::buildXrefs(void)
registerContext(csym->getName(),startbit,endbit);
}
}
if (errors > 0)
throw SleighError(s.str());
}
/// If \b this SleighBase is being reused with a new program, the context
@ -239,5 +235,8 @@ void SleighBase::restoreXml(const Element *el)
iter++;
symtab.restoreXml(*iter,this);
root = (SubtableSymbol *)symtab.getGlobalScope()->findSymbol("instruction");
buildXrefs();
vector<string> errorPairs;
buildXrefs(errorPairs);
if (!errorPairs.empty())
throw SleighError("Duplicate register pairs");
}

View file

@ -36,7 +36,7 @@ protected:
uint4 maxdelayslotbytes; ///< Maximum number of bytes in a delay-slot directive
uint4 unique_allocatemask; ///< Bits that are guaranteed to be zero in the unique allocation scheme
uint4 numSections; ///< Number of \e named sections
void buildXrefs(void); ///< Build register map. Collect user-ops and context-fields.
void buildXrefs(vector<string> &errorPairs); ///< Build register map. Collect user-ops and context-fields.
void reregisterContext(void); ///< Reregister context fields for a new executable
void restoreXml(const Element *el); ///< Read a SLEIGH specification from XML
public:

View file

@ -186,7 +186,7 @@ SubtableSymbol *WithBlock::getCurrentSubtable(const list<WithBlock> &stack)
ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,bool un,bool warndead)
{
slgh = sleigh;
compiler = sleigh;
root_symbol = rt;
unnecessarypcode = 0;
readnowrite = 0;
@ -195,16 +195,6 @@ ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,
printdeadwarning = warndead;
}
void ConsistencyChecker::reportError(const Location *loc, const string &msg)
{
slgh->reportError(loc, msg);
}
void ConsistencyChecker::reportWarning(const Location *loc, const string &msg)
{
slgh->reportWarning(loc, msg);
}
int4 ConsistencyChecker::recoverSize(const ConstTpl &sizeconst,Constructor *ct)
{
@ -245,7 +235,7 @@ void ConsistencyChecker::dealWithUnnecessaryExt(OpTpl *op,Constructor *ct)
ostringstream msg;
msg << "Unnecessary ";
printOpName(msg,op);
reportWarning(slgh->getLocation(ct), msg.str());
compiler->reportWarning(compiler->getLocation(ct), msg.str());
}
op->setOpcode(CPUI_COPY); // Equivalent to copy
unnecessarypcode += 1;
@ -258,7 +248,7 @@ void ConsistencyChecker::dealWithUnnecessaryTrunc(OpTpl *op,Constructor *ct)
ostringstream msg;
msg << "Unnecessary ";
printOpName(msg,op);
reportWarning(slgh->getLocation(ct), msg.str());
compiler->reportWarning(compiler->getLocation(ct), msg.str());
}
op->setOpcode(CPUI_COPY); // Equivalent to copy
op->removeInput(1);
@ -273,7 +263,7 @@ bool ConsistencyChecker::checkOpMisuse(OpTpl *op,Constructor *ct)
{
VarnodeTpl *vn = op->getIn(1);
if (vn->getSpace().isConstSpace() && vn->getOffset().isZero()) {
reportError(slgh->getLocation(ct), "Unsigned comparison with zero is always false");
compiler->reportError(compiler->getLocation(ct), "Unsigned comparison with zero is always false");
}
}
break;
@ -800,7 +790,7 @@ void ConsistencyChecker::printOpError(OpTpl *op,Constructor *ct,int4 err1,int4 e
printOpName(msgBuilder,op);
msgBuilder << " operator" << endl << " " << msg;
reportError(slgh->getLocation(ct), msgBuilder.str());
compiler->reportError(compiler->getLocation(ct), msgBuilder.str());
}
bool ConsistencyChecker::checkConstructorSection(Constructor *ct,ConstructTpl *cttpl)
@ -896,7 +886,7 @@ bool ConsistencyChecker::checkSubtable(SubtableSymbol *sym)
ostringstream msg;
msg << "Table '" << sym->getName() << "' exports inconsistently; ";
msg << "Constructor starting at line " << dec << ct->getLineno() << " is first inconsistency";
reportError(slgh->getLocation(ct), msg.str());
compiler->reportError(compiler->getLocation(ct), msg.str());
testresult = false;
}
seennonemptyexport = true;
@ -907,7 +897,7 @@ bool ConsistencyChecker::checkSubtable(SubtableSymbol *sym)
ostringstream msg;
msg << "Table '" << sym->getName() << "' has inconsistent export size; ";
msg << "Constructor starting at line " << dec << ct->getLineno() << " is first conflict";
reportError(slgh->getLocation(ct), msg.str());
compiler->reportError(compiler->getLocation(ct), msg.str());
testresult = false;
}
}
@ -916,7 +906,7 @@ bool ConsistencyChecker::checkSubtable(SubtableSymbol *sym)
ostringstream msg;
msg << "Table '" << sym->getName() << "' exports inconsistently; ";
msg << "Constructor starting at line " << dec << ct->getLineno() << " is first inconsistency";
reportError(slgh->getLocation(ct), msg.str());
compiler->reportError(compiler->getLocation(ct), msg.str());
testresult = false;
}
seenemptyexport = true;
@ -924,7 +914,7 @@ bool ConsistencyChecker::checkSubtable(SubtableSymbol *sym)
}
if (seennonemptyexport) {
if (tablesize == 0) {
reportWarning(slgh->getLocation(sym), "Table '" + sym->getName() + "' exports size 0");
compiler->reportWarning(compiler->getLocation(sym), "Table '" + sym->getName() + "' exports size 0");
}
sizemap[sym] = tablesize; // Remember recovered size
}
@ -1234,11 +1224,11 @@ void ConsistencyChecker::checkUnusedTemps(Constructor *ct,const map<uintb,Optimi
const OptimizeRecord &currec( (*iter).second );
if (currec.readcount == 0) {
if (printdeadwarning)
reportWarning(slgh->getLocation(ct), "Temporary is written but not read");
compiler->reportWarning(compiler->getLocation(ct), "Temporary is written but not read");
writenoread += 1;
}
else if (currec.writecount == 0) {
reportError(slgh->getLocation(ct), "Temporary is read but not written");
compiler->reportError(compiler->getLocation(ct), "Temporary is read but not written");
readnowrite += 1;
}
++iter;
@ -1883,10 +1873,15 @@ void SleighCompile::process(void)
if (errors>0) return;
buildDecisionTrees();
if (errors>0) return;
try {
buildXrefs(); // Make sure we can build crossrefs properly
} catch(SleighError &err) {
reportError(err.explain);
vector<string> errorPairs;
buildXrefs(errorPairs); // Make sure we can build crossrefs properly
if (!errorPairs.empty()) {
for(int4 i=0;i<errorPairs.size();i+=2) {
ostringstream s;
s << "Duplicate (offset,size) pair for registers: ";
s << errorPairs[i] << " and " << errorPairs[i+1] << endl;
reportError(s.str());
}
return;
}
checkUniqueAllocation();

View file

@ -93,7 +93,7 @@ class ConsistencyChecker {
OptimizeRecord(void) {
writeop = -1; readop = -1; inslot=-1; writecount=0; readcount=0; writesection=-2; readsection=-2; opttype=-1; }
};
SleighCompile *slgh;
SleighCompile *compiler;
int4 unnecessarypcode;
int4 readnowrite;
int4 writenoread;
@ -102,8 +102,6 @@ class ConsistencyChecker {
SubtableSymbol *root_symbol;
vector<SubtableSymbol *> postorder;
map<SubtableSymbol *,int4> sizemap; // Sizes associated with tables
void reportError(const Location* loc, const string &msg);
void reportWarning(const Location* loc, const string &msg);
OperandSymbol *getOperandSymbol(int4 slot,OpTpl *op,Constructor *ct);
void printOpName(ostream &s,OpTpl *op);
void printOpError(OpTpl *op,Constructor *ct,int4 err1,int4 err2,const string &message);