}
}
-//===----------------------------------------------------------------------===//
-// Instruction Analysis
-//===----------------------------------------------------------------------===//
-
-class InstAnalyzer {
- const CodeGenDAGPatterns &CDP;
- bool &mayStore;
- bool &isLoad;
- bool &NeverHasSideEffects;
-public:
- InstAnalyzer(const CodeGenDAGPatterns &cdp,
- bool &maystore, bool &isload, bool &nhse)
- : CDP(cdp), mayStore(maystore), isLoad(isload), NeverHasSideEffects(nhse) {
- }
-
- 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));
- }
-
-private:
- void AnalyzeNode(const TreePatternNode *N) {
- if (N->isLeaf()) {
- return;
- }
-
- if (N->getOperator()->getName() != "set") {
- // Get information about the SDNode for the operator.
- const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
-
- // If node writes to memory, it obviously stores to memory.
- if (OpInfo.hasProperty(SDNPMayStore)) {
- mayStore = true;
- } else 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'.
- }
- }
-
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- AnalyzeNode(N->getChild(i));
- }
-
-};
-
-void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
- bool &mayStore, bool &isLoad,
- bool &NeverHasSideEffects) {
- mayStore = isLoad = NeverHasSideEffects = false;
-
- InstAnalyzer(CDP, mayStore, isLoad, NeverHasSideEffects).Analyze(Inst.TheDef);
-
- // InstAnalyzer only correctly analyzes mayStore 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)
- fprintf(stderr,
- "Warning: mayStore flag explicitly set on instruction '%s'"
- " but flag already inferred from pattern.\n",
- Inst.TheDef->getName().c_str());
- mayStore = true;
- }
-
- // These two override everything.
- isLoad = Inst.isSimpleLoad;
- NeverHasSideEffects = Inst.neverHasSideEffects;
-
-#if 0
- // If the .td file explicitly says there is no side effect, believe it.
- if (Inst.neverHasSideEffects)
- NeverHasSideEffects = true;
-#endif
-}
-
-
//===----------------------------------------------------------------------===//
// Main Output.
//===----------------------------------------------------------------------===//
EmitSourceFileHeader("Target Instruction Descriptors", OS);
OS << "namespace llvm {\n\n";
- CodeGenTarget Target;
+ CodeGenTarget &Target = CDP.getTargetInfo();
const std::string &TargetName = Target.getName();
Record *InstrInfo = Target.getInstructionSet();
// Emit all of the operand info records.
EmitOperandInfo(OS, OperandInfoIDs);
- // Emit all of the TargetInstrDescriptor records in their ENUM ordering.
+ // Emit all of the TargetInstrDesc records in their ENUM ordering.
//
- OS << "\nstatic const TargetInstrDescriptor " << TargetName
+ OS << "\nstatic const TargetInstrDesc " << TargetName
<< "Insts[] = {\n";
std::vector<const CodeGenInstruction*> NumberedInstructions;
Target.getInstructionsByEnumValue(NumberedInstructions);
std::map<std::vector<Record*>, unsigned> &EmittedLists,
const OperandInfoMapTy &OpInfo,
std::ostream &OS) {
- // Determine properties of the instruction from its pattern.
- bool mayStore, isSimpleLoad, NeverHasSideEffects;
- InferFromPattern(Inst, mayStore, isSimpleLoad, 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);
- }
-
int MinOperands = 0;
if (!Inst.OperandList.empty())
// Each logical operand can be multiple MI operands.
MinOperands = Inst.OperandList.back().MIOperandNo +
Inst.OperandList.back().MINumOperands;
-
+
OS << " { ";
OS << Num << ",\t" << MinOperands << ",\t"
<< Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
<< ",\t\"" << Inst.TheDef->getName() << "\", 0";
// Emit all of the target indepedent flags...
- if (Inst.isReturn) OS << "|(1<<TID::Return)";
- if (Inst.isBranch) OS << "|(1<<TID::Branch)";
- if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)";
- if (Inst.isBarrier) OS << "|(1<<TID::Barrier)";
- if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)";
- if (Inst.isCall) OS << "|(1<<TID::Call)";
- if (isSimpleLoad) OS << "|(1<<TID::SimpleLoad)";
- if (mayStore) OS << "|(1<<TID::MayStore)";
- if (Inst.isImplicitDef)OS << "|(1<<TID::ImplicitDef)";
- if (Inst.isPredicable) OS << "|(1<<TID::Predicable)";
+ if (Inst.isReturn) OS << "|(1<<TID::Return)";
+ if (Inst.isBranch) OS << "|(1<<TID::Branch)";
+ if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)";
+ if (Inst.isBarrier) OS << "|(1<<TID::Barrier)";
+ if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)";
+ if (Inst.isCall) OS << "|(1<<TID::Call)";
+ if (Inst.isSimpleLoad) OS << "|(1<<TID::SimpleLoad)";
+ if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)";
+ if (Inst.mayStore) OS << "|(1<<TID::MayStore)";
+ if (Inst.isPredicable) OS << "|(1<<TID::Predicable)";
if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)";
- if (Inst.isCommutable) OS << "|(1<<TID::Commutable)";
- if (Inst.isTerminator) OS << "|(1<<TID::Terminator)";
+ if (Inst.isCommutable) OS << "|(1<<TID::Commutable)";
+ if (Inst.isTerminator) OS << "|(1<<TID::Terminator)";
if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)";
if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)";
if (Inst.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)";
if (Inst.usesCustomDAGSchedInserter)
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 (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)";
+ if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)";
OS << ", 0";
// Emit all of the target-specific flags...
if (R->getName() != "PHI" &&
R->getName() != "INLINEASM" &&
R->getName() != "LABEL" &&
+ R->getName() != "DECLARE" &&
R->getName() != "EXTRACT_SUBREG" &&
- R->getName() != "INSERT_SUBREG")
+ R->getName() != "INSERT_SUBREG" &&
+ R->getName() != "IMPLICIT_DEF" &&
+ R->getName() != "SUBREG_TO_REG")
throw R->getName() + " doesn't have a field named '" +
Val->getValue() + "'!";
return;