summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-07-04 00:09:54 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-07-04 00:09:54 +0000
commit33242fd3ed5586091e73254b58dd1825e9d53c60 (patch)
tree1cd48f1af6b26d35653abd52edd3df39f303773d /include/llvm
parent0fd518beb38568e58eeec86876bb597bab06b722 (diff)
downloadllvm-33242fd3ed5586091e73254b58dd1825e9d53c60.tar.gz
llvm-33242fd3ed5586091e73254b58dd1825e9d53c60.tar.bz2
llvm-33242fd3ed5586091e73254b58dd1825e9d53c60.tar.xz
Add an experimental early if-conversion pass, off by default.
This pass performs if-conversion on SSA form machine code by speculatively executing both sides of the branch and using a cmov instruction to select the result. This can help lower the number of branch mispredictions on architectures like x86 that don't have predicable instructions. The current implementation is very aggressive, and causes regressions on mosts tests. It needs good heuristics that have yet to be implemented. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159694 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/CodeGen/Passes.h4
-rw-r--r--include/llvm/InitializePasses.h1
-rw-r--r--include/llvm/Target/TargetInstrInfo.h50
3 files changed, 55 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 4a24ab0d63..c80f6dcdb5 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -392,6 +392,10 @@ namespace llvm {
/// into tails of their predecessors.
extern char &TailDuplicateID;
+ /// EarlyIfConverter - This pass performs if-conversion on SSA form by
+ /// inserting cmov instructions.
+ extern char &EarlyIfConverterID;
+
/// IfConverter - This pass performs machine code if conversion.
extern char &IfConverterID;
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index c2cb7c218b..e6fa8c3d30 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -100,6 +100,7 @@ void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierPass(PassRegistry&);
void initializeDominatorTreePass(PassRegistry&);
+void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeEdgeProfilerPass(PassRegistry&);
void initializeExpandPostRAPass(PassRegistry&);
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index f096946b38..73efc507fa 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -369,6 +369,56 @@ public:
return false;
}
+ /// canInsertSelect - Return true if it is possible to insert a select
+ /// instruction that chooses between TrueReg and FalseReg based on the
+ /// condition code in Cond.
+ ///
+ /// When successful, also return the latency in cycles from TrueReg,
+ /// FalseReg, and Cond to the destination register. The Cond latency should
+ /// compensate for a conditional branch being removed. For example, if a
+ /// conditional branch has a 3 cycle latency from the condition code read,
+ /// and a cmov instruction has a 2 cycle latency from the condition code
+ /// read, CondCycles should be returned as -1.
+ ///
+ /// @param MBB Block where select instruction would be inserted.
+ /// @param Cond Condition returned by AnalyzeBranch.
+ /// @param TrueReg Virtual register to select when Cond is true.
+ /// @param FalseReg Virtual register to select when Cond is false.
+ /// @param CondCycles Latency from Cond+Branch to select output.
+ /// @param TrueCycles Latency from TrueReg to select output.
+ /// @param FalseCycles Latency from FalseReg to select output.
+ virtual bool canInsertSelect(const MachineBasicBlock &MBB,
+ const SmallVectorImpl<MachineOperand> &Cond,
+ unsigned TrueReg, unsigned FalseReg,
+ int &CondCycles,
+ int &TrueCycles, int &FalseCycles) const {
+ return false;
+ }
+
+ /// insertSelect - Insert a select instruction into MBB before I that will
+ /// copy TrueReg to DstReg when Cond is true, and FalseReg to DstReg when
+ /// Cond is false.
+ ///
+ /// This function can only be called after canInsertSelect() returned true.
+ /// The condition in Cond comes from AnalyzeBranch, and it can be assumed
+ /// that the same flags or registers required by Cond are available at the
+ /// insertion point.
+ ///
+ /// @param MBB Block where select instruction should be inserted.
+ /// @param I Insertion point.
+ /// @param DL Source location for debugging.
+ /// @param DstReg Virtual register to be defined by select instruction.
+ /// @param Cond Condition as computed by AnalyzeBranch.
+ /// @param TrueReg Virtual register to copy when Cond is true.
+ /// @param FalseReg Virtual register to copy when Cons is false.
+ virtual void insertSelect(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I, DebugLoc DL,
+ unsigned DstReg,
+ const SmallVectorImpl<MachineOperand> &Cond,
+ unsigned TrueReg, unsigned FalseReg) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
+ }
+
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,