diff options
author | Bill Wendling <isanbard@gmail.com> | 2008-05-28 22:54:52 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2008-05-28 22:54:52 +0000 |
commit | 8370d38adee63b3a4d87bfe81be4aacc55fe7cda (patch) | |
tree | 4689ca3c0b6ee971d3aef6ec8536642eefb377a8 | |
parent | a8db14796b22ba7798ef94fc831d56c8a11d4e2a (diff) | |
download | llvm-8370d38adee63b3a4d87bfe81be4aacc55fe7cda.tar.gz llvm-8370d38adee63b3a4d87bfe81be4aacc55fe7cda.tar.bz2 llvm-8370d38adee63b3a4d87bfe81be4aacc55fe7cda.tar.xz |
Add a flag to indicate that an instruction is as cheap (or cheaper) than a move
instruction to execute. This can be used for transformations (like two-address
conversion) to remat an instruction instead of generating a "move"
instruction. The idea is to decrease the live ranges and register pressure and
all that jazz.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51660 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Target/TargetInstrDesc.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 6 | ||||
-rw-r--r-- | lib/Target/Target.td | 5 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 1 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.h | 5 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 27 |
6 files changed, 37 insertions, 19 deletions
diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h index dbfd55a7fb..c83f8e21fb 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/Target/TargetInstrDesc.h @@ -95,7 +95,8 @@ namespace TID { Commutable, ConvertibleTo3Addr, UsesCustomDAGSchedInserter, - Rematerializable + Rematerializable, + CheapAsAMove }; } @@ -387,6 +388,15 @@ public: bool isRematerializable() const { return Flags & (1 << TID::Rematerializable); } + + /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or + /// less) than a move instruction. This is useful during certain types of + /// rematerializations (e.g., during two-address conversion) where we would + /// like to remat the instruction, but not if it costs more than moving the + /// instruction into the appropriate register. + bool isAsCheapAsAMove() const { + return Flags & (1 << TID::CheapAsAMove); + } }; } // end namespace llvm diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 135718acc7..e008c9a61b 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -639,9 +639,9 @@ void MachineInstr::copyPredicates(const MachineInstr *MI) { } } -/// isSafeToMove - Return true if it is safe to this instruction. If SawStore -/// true, it means there is a store (or call) between the instruction the -/// localtion and its intended destination. +/// isSafeToMove - Return true if it is safe to this instruction. If SawStore is +/// set to true, it means that there is a store (or call) between the +/// instruction's location and its intended destination. bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, bool &SawStore) { // Ignore stuff that we obviously can't move. if (TID->mayStore() || TID->isCall()) { diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 6e2ba91b95..a268e16410 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -203,22 +203,25 @@ class Instruction { bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? + bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. // Side effect flags - When set, the flags have these meanings: // // hasSideEffects - The instruction has side effects that are not // captured by any operands of the instruction or other flags. + // // mayHaveSideEffects - Some instances of the instruction can have side // effects. The virtual method "isReallySideEffectFree" is called to // determine this. Load instructions are an example of where this is // useful. In general, loads always have side effects. However, loads from // constant pools don't. Individual back ends make this determination. + // // neverHasSideEffects - Set on an instruction with no pattern if it has no // side effects. bit hasSideEffects = 0; bit mayHaveSideEffects = 0; bit neverHasSideEffects = 0; - + InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. string Constraints = ""; // OperandConstraint, e.g. $src = $dst. diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 53daf9d944..37c2069ec7 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -99,6 +99,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) hasSideEffects = R->getValueAsBit("hasSideEffects"); mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); + isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove"); hasOptionalDef = false; isVariadic = false; diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 9bfd4323f9..0727e38c53 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -102,7 +102,10 @@ namespace llvm { bool hasCtrlDep; bool isNotDuplicable; bool hasOptionalDef; - bool hasSideEffects, mayHaveSideEffects, neverHasSideEffects; + bool hasSideEffects; + bool mayHaveSideEffects; + bool neverHasSideEffects; + bool isAsCheapAsAMove; /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", /// where $foo is a whole operand and $foo.bar refers to a suboperand. diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 57d72b436e..028fbeb88b 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -208,26 +208,27 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, << ",\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 (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.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.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; + if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; + if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; OS << ", 0"; // Emit all of the target-specific flags... |