mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
Heed guessInstructionProperties, and stop warning on redundant flags.
Emit TableGen errors if guessInstructionProperties is 0 and instruction properties can't be inferred from patterns. Allow explicit instruction properties even when they can be inferred. This patch doesn't change the TableGen output. Redundant properties are not yet verified because the tree has errors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162516 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -2367,36 +2367,25 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
|
|||||||
|
|
||||||
class InstAnalyzer {
|
class InstAnalyzer {
|
||||||
const CodeGenDAGPatterns &CDP;
|
const CodeGenDAGPatterns &CDP;
|
||||||
bool &mayStore;
|
|
||||||
bool &mayLoad;
|
|
||||||
bool &IsBitcast;
|
|
||||||
bool &HasSideEffects;
|
|
||||||
bool &IsVariadic;
|
|
||||||
public:
|
public:
|
||||||
InstAnalyzer(const CodeGenDAGPatterns &cdp,
|
bool hasSideEffects;
|
||||||
bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv)
|
bool mayStore;
|
||||||
: CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc),
|
bool mayLoad;
|
||||||
HasSideEffects(hse), IsVariadic(isv) {
|
bool isBitcast;
|
||||||
}
|
bool isVariadic;
|
||||||
|
|
||||||
/// Analyze - Analyze the specified instruction, returning true if the
|
InstAnalyzer(const CodeGenDAGPatterns &cdp)
|
||||||
/// instruction had a pattern.
|
: CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false),
|
||||||
bool Analyze(Record *InstRecord) {
|
isBitcast(false), isVariadic(false) {}
|
||||||
const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
|
|
||||||
if (Pattern == 0) {
|
|
||||||
HasSideEffects = 1;
|
|
||||||
return false; // No pattern.
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Assume only the first tree is the pattern. The others are clobber
|
void Analyze(const TreePattern *Pat) {
|
||||||
// nodes.
|
// Assume only the first tree is the pattern. The others are clobber nodes.
|
||||||
AnalyzeNode(Pattern->getTree(0));
|
AnalyzeNode(Pat->getTree(0));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsNodeBitcast(const TreePatternNode *N) const {
|
bool IsNodeBitcast(const TreePatternNode *N) const {
|
||||||
if (HasSideEffects || mayLoad || mayStore || IsVariadic)
|
if (hasSideEffects || mayLoad || mayStore || isVariadic)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (N->getNumChildren() != 2)
|
if (N->getNumChildren() != 2)
|
||||||
@ -2427,7 +2416,7 @@ private:
|
|||||||
const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
|
const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
|
||||||
if (CP.hasProperty(SDNPMayStore)) mayStore = true;
|
if (CP.hasProperty(SDNPMayStore)) mayStore = true;
|
||||||
if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
|
if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
|
||||||
if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
|
if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -2439,7 +2428,7 @@ private:
|
|||||||
|
|
||||||
// Ignore set nodes, which are not SDNodes.
|
// Ignore set nodes, which are not SDNodes.
|
||||||
if (N->getOperator()->getName() == "set") {
|
if (N->getOperator()->getName() == "set") {
|
||||||
IsBitcast = IsNodeBitcast(N);
|
isBitcast = IsNodeBitcast(N);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2449,8 +2438,8 @@ private:
|
|||||||
// Notice properties of the node.
|
// Notice properties of the node.
|
||||||
if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
|
if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
|
||||||
if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
|
if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
|
||||||
if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
|
if (OpInfo.hasProperty(SDNPSideEffect)) hasSideEffects = true;
|
||||||
if (OpInfo.hasProperty(SDNPVariadic)) IsVariadic = true;
|
if (OpInfo.hasProperty(SDNPVariadic)) isVariadic = true;
|
||||||
|
|
||||||
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
|
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
|
||||||
// If this is an intrinsic, analyze it.
|
// If this is an intrinsic, analyze it.
|
||||||
@ -2462,62 +2451,27 @@ private:
|
|||||||
|
|
||||||
if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
|
if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
|
||||||
// WriteMem intrinsics can have other strange effects.
|
// WriteMem intrinsics can have other strange effects.
|
||||||
HasSideEffects = true;
|
hasSideEffects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void InferFromPattern(const CodeGenInstruction &Inst,
|
static void InferFromPattern(CodeGenInstruction &InstInfo,
|
||||||
bool &MayStore, bool &MayLoad,
|
const InstAnalyzer &PatInfo,
|
||||||
bool &IsBitcast,
|
Record *PatDef) {
|
||||||
bool &HasSideEffects, bool &IsVariadic,
|
// Remember where InstInfo got its flags.
|
||||||
const CodeGenDAGPatterns &CDP) {
|
if (InstInfo.hasUndefFlags())
|
||||||
MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false;
|
InstInfo.InferredFrom = PatDef;
|
||||||
|
|
||||||
bool HadPattern =
|
// Transfer inferred flags.
|
||||||
InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic)
|
InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
|
||||||
.Analyze(Inst.TheDef);
|
InstInfo.mayStore |= PatInfo.mayStore;
|
||||||
|
InstInfo.mayLoad |= PatInfo.mayLoad;
|
||||||
|
|
||||||
// InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
|
// These flags are silently added without any verification.
|
||||||
if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
|
InstInfo.isBitcast |= PatInfo.isBitcast;
|
||||||
// If we decided that this is a store from the pattern, then the .td file
|
InstInfo.Operands.isVariadic |= PatInfo.isVariadic;
|
||||||
// entry is redundant.
|
|
||||||
if (MayStore)
|
|
||||||
PrintWarning(Inst.TheDef->getLoc(),
|
|
||||||
"mayStore flag explicitly set on "
|
|
||||||
"instruction, but flag already inferred from pattern.");
|
|
||||||
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)
|
|
||||||
PrintWarning(Inst.TheDef->getLoc(),
|
|
||||||
"mayLoad flag explicitly set on "
|
|
||||||
"instruction, but flag already inferred from pattern.");
|
|
||||||
MayLoad = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Inst.neverHasSideEffects) {
|
|
||||||
if (HadPattern)
|
|
||||||
PrintWarning(Inst.TheDef->getLoc(),
|
|
||||||
"neverHasSideEffects flag explicitly set on "
|
|
||||||
"instruction, but flag already inferred from pattern.");
|
|
||||||
HasSideEffects = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Inst.hasSideEffects) {
|
|
||||||
if (HasSideEffects)
|
|
||||||
PrintWarning(Inst.TheDef->getLoc(),
|
|
||||||
"hasSideEffects flag explicitly set on "
|
|
||||||
"instruction, but flag already inferred from pattern.");
|
|
||||||
HasSideEffects = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Inst.Operands.isVariadic)
|
|
||||||
IsVariadic = true; // Can warn if we want.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// hasNullFragReference - Return true if the DAG has any reference to the
|
/// hasNullFragReference - Return true if the DAG has any reference to the
|
||||||
@ -2852,24 +2806,60 @@ void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern,
|
|||||||
void CodeGenDAGPatterns::InferInstructionFlags() {
|
void CodeGenDAGPatterns::InferInstructionFlags() {
|
||||||
const std::vector<const CodeGenInstruction*> &Instructions =
|
const std::vector<const CodeGenInstruction*> &Instructions =
|
||||||
Target.getInstructionsByEnumValue();
|
Target.getInstructionsByEnumValue();
|
||||||
|
|
||||||
|
// First try to infer flags from the primary instruction pattern, if any.
|
||||||
|
SmallVector<CodeGenInstruction*, 8> Revisit;
|
||||||
for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
|
||||||
CodeGenInstruction &InstInfo =
|
CodeGenInstruction &InstInfo =
|
||||||
const_cast<CodeGenInstruction &>(*Instructions[i]);
|
const_cast<CodeGenInstruction &>(*Instructions[i]);
|
||||||
// Determine properties of the instruction from its pattern.
|
|
||||||
bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic;
|
|
||||||
InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast,
|
|
||||||
HasSideEffects, IsVariadic, *this);
|
|
||||||
InstInfo.mayStore = MayStore;
|
|
||||||
InstInfo.mayLoad = MayLoad;
|
|
||||||
InstInfo.isBitcast = IsBitcast;
|
|
||||||
InstInfo.hasSideEffects = HasSideEffects;
|
|
||||||
InstInfo.Operands.isVariadic = IsVariadic;
|
|
||||||
|
|
||||||
// Sanity checks.
|
// Treat neverHasSideEffects = 1 as the equivalent of hasSideEffects = 0.
|
||||||
if (InstInfo.isReMaterializable && InstInfo.hasSideEffects)
|
// This flag is obsolete and will be removed.
|
||||||
throw TGError(InstInfo.TheDef->getLoc(), "The instruction " +
|
if (InstInfo.neverHasSideEffects) {
|
||||||
InstInfo.TheDef->getName() +
|
assert(!InstInfo.hasSideEffects);
|
||||||
" is rematerializable AND has unmodeled side effects?");
|
InstInfo.hasSideEffects_Unset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the primary instruction pattern.
|
||||||
|
const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern();
|
||||||
|
if (!Pattern) {
|
||||||
|
if (InstInfo.hasUndefFlags())
|
||||||
|
Revisit.push_back(&InstInfo);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
InstAnalyzer PatInfo(*this);
|
||||||
|
PatInfo.Analyze(Pattern);
|
||||||
|
InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revisit instructions with undefined flags and no pattern.
|
||||||
|
if (Target.guessInstructionProperties()) {
|
||||||
|
for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
|
||||||
|
CodeGenInstruction &InstInfo = *Revisit[i];
|
||||||
|
if (InstInfo.InferredFrom)
|
||||||
|
continue;
|
||||||
|
// The mayLoad and mayStore flags default to false.
|
||||||
|
// Conservatively assume hasSideEffects if it wasn't explicit.
|
||||||
|
if (InstInfo.hasSideEffects_Unset)
|
||||||
|
InstInfo.hasSideEffects = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complain about any flags that are still undefined.
|
||||||
|
for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
|
||||||
|
CodeGenInstruction &InstInfo = *Revisit[i];
|
||||||
|
if (InstInfo.InferredFrom)
|
||||||
|
continue;
|
||||||
|
if (InstInfo.hasSideEffects_Unset)
|
||||||
|
PrintError(InstInfo.TheDef->getLoc(),
|
||||||
|
"Can't infer hasSideEffects from patterns");
|
||||||
|
if (InstInfo.mayStore_Unset)
|
||||||
|
PrintError(InstInfo.TheDef->getLoc(),
|
||||||
|
"Can't infer mayStore from patterns");
|
||||||
|
if (InstInfo.mayLoad_Unset)
|
||||||
|
PrintError(InstInfo.TheDef->getLoc(),
|
||||||
|
"Can't infer mayLoad from patterns");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,8 @@ void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
|
|||||||
// CodeGenInstruction Implementation
|
// CodeGenInstruction Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) {
|
CodeGenInstruction::CodeGenInstruction(Record *R)
|
||||||
|
: TheDef(R), Operands(R), InferredFrom(0) {
|
||||||
Namespace = R->getValueAsString("Namespace");
|
Namespace = R->getValueAsString("Namespace");
|
||||||
AsmString = R->getValueAsString("AsmString");
|
AsmString = R->getValueAsString("AsmString");
|
||||||
|
|
||||||
|
@ -249,6 +249,14 @@ namespace llvm {
|
|||||||
bool isCodeGenOnly;
|
bool isCodeGenOnly;
|
||||||
bool isPseudo;
|
bool isPseudo;
|
||||||
|
|
||||||
|
/// Are there any undefined flags?
|
||||||
|
bool hasUndefFlags() const {
|
||||||
|
return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The record used to infer instruction flags, or NULL if no flag values
|
||||||
|
// have been inferred.
|
||||||
|
Record *InferredFrom;
|
||||||
|
|
||||||
CodeGenInstruction(Record *R);
|
CodeGenInstruction(Record *R);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user