summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2008-05-28 22:54:52 +0000
committerBill Wendling <isanbard@gmail.com>2008-05-28 22:54:52 +0000
commit8370d38adee63b3a4d87bfe81be4aacc55fe7cda (patch)
tree4689ca3c0b6ee971d3aef6ec8536642eefb377a8
parenta8db14796b22ba7798ef94fc831d56c8a11d4e2a (diff)
downloadllvm-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.h12
-rw-r--r--lib/CodeGen/MachineInstr.cpp6
-rw-r--r--lib/Target/Target.td5
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp1
-rw-r--r--utils/TableGen/CodeGenInstruction.h5
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp27
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...