summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/Analysis/DivergenceAnalysis.h4
-rw-r--r--llvm/include/llvm/CodeGen/FunctionLoweringInfo.h11
-rw-r--r--llvm/include/llvm/CodeGen/SelectionDAG.h33
-rw-r--r--llvm/include/llvm/CodeGen/SelectionDAGNodes.h6
-rw-r--r--llvm/include/llvm/CodeGen/TargetLowering.h11
5 files changed, 49 insertions, 16 deletions
diff --git a/llvm/include/llvm/Analysis/DivergenceAnalysis.h b/llvm/include/llvm/Analysis/DivergenceAnalysis.h
index aa2de571ba1..dd3c68e2dd6 100644
--- a/llvm/include/llvm/Analysis/DivergenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DivergenceAnalysis.h
@@ -13,6 +13,8 @@
// better decisions.
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_ANALYSIS_DIVERGENCE_ANALYSIS_H
+#define LLVM_ANALYSIS_DIVERGENCE_ANALYSIS_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/Function.h"
@@ -46,3 +48,5 @@ private:
DenseSet<const Value *> DivergentValues;
};
} // End llvm namespace
+
+#endif //LLVM_ANALYSIS_DIVERGENCE_ANALYSIS_H \ No newline at end of file
diff --git a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
index 3b39d87ffb4..24f5cd7cc66 100644
--- a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -118,6 +118,17 @@ public:
/// cross-basic-block values.
DenseMap<const Value *, unsigned> ValueMap;
+ /// VirtReg2Value map is needed by the Divergence Analysis driven
+ /// instruction selection. It is reverted ValueMap. It is computed
+ /// in lazy style - on demand. It is used to get the Value corresponding
+ /// to the live in virtual register and is called from the
+ /// TargetLowerinInfo::isSDNodeSourceOfDivergence.
+ DenseMap<unsigned, const Value*> VirtReg2Value;
+
+ /// This method is called from TargetLowerinInfo::isSDNodeSourceOfDivergence
+ /// to get the Value corresponding to the live-in virtual register.
+ const Value * getValueFromVirtualReg(unsigned Vreg);
+
/// Track virtual registers created for exception pointers.
DenseMap<const Value *, unsigned> CatchPadExceptionPointers;
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index cf8618b76e2..0df75cb0b1d 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -28,8 +28,10 @@
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/DivergenceAnalysis.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineValueType.h"
@@ -217,6 +219,9 @@ class SelectionDAG {
LLVMContext *Context;
CodeGenOpt::Level OptLevel;
+ DivergenceAnalysis * DA = nullptr;
+ FunctionLoweringInfo * FLI = nullptr;
+
/// The function-level optimization remark emitter. Used to emit remarks
/// whenever manipulating the DAG.
OptimizationRemarkEmitter *ORE;
@@ -346,19 +351,7 @@ private:
.getRawSubclassData();
}
- void createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
- assert(!Node->OperandList && "Node already has operands");
- SDUse *Ops = OperandRecycler.allocate(
- ArrayRecycler<SDUse>::Capacity::get(Vals.size()), OperandAllocator);
-
- for (unsigned I = 0; I != Vals.size(); ++I) {
- Ops[I].setUser(Node);
- Ops[I].setInitial(Vals[I]);
- }
- Node->NumOperands = Vals.size();
- Node->OperandList = Ops;
- checkForCycles(Node);
- }
+ void createOperands(SDNode *Node, ArrayRef<SDValue> Vals);
void removeOperands(SDNode *Node) {
if (!Node->OperandList)
@@ -369,7 +362,7 @@ private:
Node->NumOperands = 0;
Node->OperandList = nullptr;
}
-
+ void CreateTopologicalOrder(std::vector<SDNode*>& Order);
public:
explicit SelectionDAG(const TargetMachine &TM, CodeGenOpt::Level);
SelectionDAG(const SelectionDAG &) = delete;
@@ -378,7 +371,12 @@ public:
/// Prepare this SelectionDAG to process code in the given MachineFunction.
void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE,
- Pass *PassPtr, const TargetLibraryInfo *LibraryInfo);
+ Pass *PassPtr, const TargetLibraryInfo *LibraryInfo,
+ DivergenceAnalysis * DA);
+
+ void setFunctionLoweringInfo(FunctionLoweringInfo * FuncInfo) {
+ FLI = FuncInfo;
+ }
/// Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
@@ -463,6 +461,8 @@ public:
return Root;
}
+ void VerifyDAGDiverence();
+
/// This iterates over the nodes in the SelectionDAG, folding
/// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and
@@ -1128,6 +1128,9 @@ public:
SDValue Op3, SDValue Op4, SDValue Op5);
SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
+ // Propagates the change in divergence to users
+ void updateDivergence(SDNode * N);
+
/// These are used for target selectors to *mutate* the
/// specified node to have the specified return type, Target opcode, and
/// operands. Note that target opcodes are stored as
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 613697bb558..ab25b8a7b2c 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -466,11 +466,13 @@ protected:
friend class SDNode;
friend class MemIntrinsicSDNode;
friend class MemSDNode;
+ friend class SelectionDAG;
uint16_t HasDebugValue : 1;
uint16_t IsMemIntrinsic : 1;
+ uint16_t IsDivergent : 1;
};
- enum { NumSDNodeBits = 2 };
+ enum { NumSDNodeBits = 3 };
class ConstantSDNodeBitfields {
friend class ConstantSDNode;
@@ -662,6 +664,8 @@ public:
bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
+ bool isDivergent() const { return SDNodeBits.IsDivergent; }
+
/// Return true if there are no uses of this node.
bool use_empty() const { return UseList == nullptr; }
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 10671f4db2e..d3ead5f854d 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/DivergenceAnalysis.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineValueType.h"
@@ -2562,6 +2563,16 @@ public:
bool isPositionIndependent() const;
+ virtual bool isSDNodeSourceOfDivergence(const SDNode *N,
+ FunctionLoweringInfo *FLI,
+ DivergenceAnalysis *DA) const {
+ return false;
+ }
+
+ virtual bool isSDNodeAlwaysUniform(const SDNode * N) const {
+ return false;
+ }
+
/// Returns true by value, base pointer and offset pointer and addressing mode
/// by reference if the node's address can be legally represented as
/// pre-indexed load / store address.
OpenPOWER on IntegriCloud