1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Check all patterns for missing instruction flags.

Both single-instruction and multi-instruction patterns can be checked
for missing mayLoad / mayStore, and hasSideEffects flags.

llvm-svn: 162734
This commit is contained in:
Jakob Stoklund Olesen 2012-08-28 03:26:49 +00:00
parent 93b4cf4daf
commit 24cfc3f83b
2 changed files with 72 additions and 0 deletions

View File

@ -2027,6 +2027,9 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) :
// stores, and side effects in many cases by examining an
// instruction's pattern.
InferInstructionFlags();
// Verify that instruction flags match the patterns.
VerifyInstructionFlags();
}
CodeGenDAGPatterns::~CodeGenDAGPatterns() {
@ -2405,6 +2408,7 @@ private:
return OpInfo.getEnumName() == "ISD::BITCAST";
}
public:
void AnalyzeNode(const TreePatternNode *N) {
if (N->isLeaf()) {
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
@ -2937,6 +2941,73 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
}
}
/// Verify instruction flags against pattern node properties.
void CodeGenDAGPatterns::VerifyInstructionFlags() {
unsigned Errors = 0;
for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) {
const PatternToMatch &PTM = *I;
SmallVector<Record*, 8> Instrs;
getInstructionsInTree(PTM.getDstPattern(), Instrs);
if (Instrs.empty())
continue;
// Count the number of instructions with each flag set.
unsigned NumSideEffects = 0;
unsigned NumStores = 0;
unsigned NumLoads = 0;
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
NumSideEffects += InstInfo.hasSideEffects;
NumStores += InstInfo.mayStore;
NumLoads += InstInfo.mayLoad;
}
// Analyze the source pattern.
InstAnalyzer PatInfo(*this);
PatInfo.Analyze(&PTM);
// Collect error messages.
SmallVector<std::string, 4> Msgs;
// Check for missing flags in the output.
// Permit extra flags for now at least.
if (PatInfo.hasSideEffects && !NumSideEffects)
Msgs.push_back("pattern has side effects, but hasSideEffects isn't set");
// Don't verify store flags on instructions with side effects. At least for
// intrinsics, side effects implies mayStore.
if (!PatInfo.hasSideEffects && PatInfo.mayStore && !NumStores)
Msgs.push_back("pattern may store, but mayStore isn't set");
// Similarly, mayStore implies mayLoad on intrinsics.
if (!PatInfo.mayStore && PatInfo.mayLoad && !NumLoads)
Msgs.push_back("pattern may load, but mayLoad isn't set");
// Print error messages.
if (Msgs.empty())
continue;
++Errors;
for (unsigned i = 0, e = Msgs.size(); i != e; ++i)
PrintError(PTM.getSrcRecord()->getLoc(), Twine(Msgs[i]) + " on the " +
(Instrs.size() == 1 ?
"instruction" : "output instructions"));
// Provide the location of the relevant instruction definitions.
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
if (Instrs[i] != PTM.getSrcRecord())
PrintError(Instrs[i]->getLoc(), "defined here");
const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
if (InstInfo.InferredFrom &&
InstInfo.InferredFrom != InstInfo.TheDef &&
InstInfo.InferredFrom != PTM.getSrcRecord())
PrintError(InstInfo.InferredFrom->getLoc(), "inferred from patttern");
}
}
if (Errors)
throw "Errors in DAG patterns";
}
/// Given a pattern result with an unresolved type, see if we can find one
/// instruction with an unresolved result type. Force this result type to an
/// arbitrary element if it's possible types to converge results.

View File

@ -797,6 +797,7 @@ private:
void ParsePatterns();
void InferInstructionFlags();
void GenerateVariants();
void VerifyInstructionFlags();
void AddPatternToMatch(const TreePattern *Pattern, const PatternToMatch &PTM);
void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,