start inferring 'no side effects'.

llvm-svn: 45822
This commit is contained in:
Chris Lattner 2008-01-10 05:39:30 +00:00
parent 94de7bc3aa
commit 42c63ef96e
4 changed files with 62 additions and 56 deletions

View File

@ -321,6 +321,8 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
Properties |= 1 << SDNPMayStore;
} else if (PropList[i]->getName() == "SDNPMayLoad") {
Properties |= 1 << SDNPMayLoad;
} else if (PropList[i]->getName() == "SDNPSideEffect") {
Properties |= 1 << SDNPSideEffect;
} else {
cerr << "Unknown SD Node property '" << PropList[i]->getName()
<< "' on node '" << R->getName() << "'!\n";

View File

@ -38,7 +38,8 @@ enum SDNP {
SDNPInFlag,
SDNPOptInFlag,
SDNPMayLoad,
SDNPMayStore
SDNPMayStore,
SDNPSideEffect
};
/// getValueType - Return the MVT::ValueType that the specified TableGen record

View File

@ -145,20 +145,17 @@ class InstAnalyzer {
const CodeGenDAGPatterns &CDP;
bool &mayStore;
bool &mayLoad;
bool &NeverHasSideEffects;
bool &HasSideEffects;
public:
InstAnalyzer(const CodeGenDAGPatterns &cdp,
bool &maystore, bool &mayload, bool &nhse)
: CDP(cdp), mayStore(maystore), mayLoad(mayload), NeverHasSideEffects(nhse){
bool &maystore, bool &mayload, bool &hse)
: CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
}
void Analyze(Record *InstRecord) {
const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
if (Pattern == 0) return; // No pattern.
// Assume there is no side-effect unless we see one.
NeverHasSideEffects = true;
// FIXME: Assume only the first tree is the pattern. The others are clobber
// nodes.
AnalyzeNode(Pattern->getTree(0));
@ -169,7 +166,14 @@ private:
if (N->isLeaf())
return;
if (N->getOperator()->getName() != "set") {
// Analyze children.
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
AnalyzeNode(N->getChild(i));
// Ignore set nodes, which are not SDNodes.
if (N->getOperator()->getName() == "set")
return;
// Get information about the SDNode for the operator.
const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
@ -181,61 +185,66 @@ private:
if (OpInfo.hasProperty(SDNPMayLoad))
mayLoad = true;
// If it reads memory, remember this.
if (OpInfo.hasProperty(SDNPSideEffect))
HasSideEffects = true;
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
// If this is an intrinsic, analyze it.
if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) {
mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
}
if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
mayLoad = true;// These may also load memory.
}
}
mayLoad = true;// These may load memory.
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
AnalyzeNode(N->getChild(i));
if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
// WriteMem intrinsics can have other strange effects.
HasSideEffects = true;
}
}
};
void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
bool &mayStore, bool &mayLoad,
bool &NeverHasSideEffects) {
mayStore = mayLoad = NeverHasSideEffects = false;
bool &MayStore, bool &MayLoad,
bool &HasSideEffects) {
MayStore = MayLoad = HasSideEffects = false;
InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef);
InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
// InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
// If we decided that this is a store from the pattern, then the .td file
// entry is redundant.
if (mayStore)
if (MayStore)
fprintf(stderr,
"Warning: mayStore flag explicitly set on instruction '%s'"
" but flag already inferred from pattern.\n",
Inst.TheDef->getName().c_str());
mayStore = true;
MayStore = true;
}
if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it.
// If we decided that this is a load from the pattern, then the .td file
// entry is redundant.
if (mayLoad)
if (MayLoad)
fprintf(stderr,
"Warning: mayLoad flag explicitly set on instruction '%s'"
" but flag already inferred from pattern.\n",
Inst.TheDef->getName().c_str());
mayLoad = true;
MayLoad = true;
}
NeverHasSideEffects = Inst.neverHasSideEffects;
#if 0
// If the .td file explicitly says there is no side effect, believe it.
if (Inst.neverHasSideEffects)
NeverHasSideEffects = true;
#endif
if (Inst.neverHasSideEffects) {
// If we already decided that this instruction has no side effects, then the
// .td file entry is redundant.
if (!HasSideEffects)
fprintf(stderr,
"Warning: neverHasSideEffects flag explicitly set on instruction"
" '%s' but flag already inferred from pattern.\n",
Inst.TheDef->getName().c_str());
HasSideEffects = false;
}
}
@ -299,14 +308,8 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
const OperandInfoMapTy &OpInfo,
std::ostream &OS) {
// Determine properties of the instruction from its pattern.
bool mayStore, mayLoad, NeverHasSideEffects;
InferFromPattern(Inst, mayStore, mayLoad, NeverHasSideEffects);
if (NeverHasSideEffects && Inst.mayHaveSideEffects) {
std::cerr << "error: Instruction '" << Inst.TheDef->getName()
<< "' is marked with 'mayHaveSideEffects', but it can never have them!\n";
exit(1);
}
bool mayStore, mayLoad, HasSideEffects;
InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects);
int MinOperands = 0;
if (!Inst.OperandList.empty())
@ -341,7 +344,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
OS << "|(1<<TID::UsesCustomDAGSchedInserter)";
if (Inst.isVariadic) OS << "|(1<<TID::Variadic)";
if (Inst.mayHaveSideEffects) OS << "|(1<<TID::MayHaveSideEffects)";
if (NeverHasSideEffects) OS << "|(1<<TID::NeverHasSideEffects)";
if (!HasSideEffects) OS << "|(1<<TID::NeverHasSideEffects)";
OS << ", 0";
// Emit all of the target-specific flags...

View File

@ -43,7 +43,7 @@ private:
// Instruction analysis.
void InferFromPattern(const CodeGenInstruction &Inst,
bool &isStore, bool &isLoad, bool &NeverHasSideEffects);
bool &MayStore, bool &MayLoad, bool &HasSideEffects);
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,