Commit 3bb520c8 authored by Junjie Gu's avatar Junjie Gu Committed by gbsbuild

All nodes of congruent class (CC) are linked. The previous

implementation keeps an isolated node in that link. This change
will remove an isolated node from the link and put it in a
separate congruent class (single-valued, thus isolated).

This change will make it be able to do re-union nodes from different
congruent class later after DeSSA is done. And this change seems
easier to understand as well.

The first version of this change had a bug (did not reset leader
always once a node is removed), which is fixed in this change.
Also, for the existing Path Halving (getLeader), it did not set
the parent node correctly, though this is not correctness issue
but bad for performance, which is also fixed in this change

Change-Id: I8976dd394d24034cef388f4fbe4e2f77be62af79
parent 02fa9bfb
......@@ -324,6 +324,7 @@ void DeSSA::MapAddReg(MapVector<Value*, Node*> &Map, Value *Val, e_alignment Ali
Map[Val] = new (Allocator) Node(Val, ++CurrColor, Align);
// Using Path Halving in union-find
DeSSA::Node::getLeader() {
Node *N = this;
......@@ -333,7 +334,7 @@ DeSSA::Node::getLeader() {
while (Parent != Grandparent) {
N = Grandparent;
Parent = Parent->parent.getPointer();
Parent = N->parent.getPointer();
Grandparent = Parent->parent.getPointer();
......@@ -402,6 +403,7 @@ void DeSSA::MapUnionRegs(MapVector<Value*, Node*> &Map, Value* Val1, Value* Val2
void DeSSA::isolateReg(Value* Val) {
Node *Node = RegNodeMap[Val];
Node->parent.setInt(Node->parent.getInt() | Node::kRegisterIsolatedFlag);
......@@ -428,6 +430,7 @@ Value* DeSSA::getPHIRoot(Instruction *PHI) const {
void DeSSA::isolatePHI(Instruction *PHI) {
Node *Node = RegNodeMap[PHI];
Node->parent.setInt(Node->parent.getInt() | Node::kPHIIsolatedFlag);
......@@ -438,6 +441,58 @@ bool DeSSA::isPHIIsolated(Instruction *PHI) const {
return ((DestNode->parent.getInt() & Node::kPHIIsolatedFlag) > 0 ? true : false);
// Split node ND from its existing congurent class, and the
// node ND itself becomes a new single-value congruent class.
void DeSSA::splitNode(Node* ND)
Node* N = ND->next;
if (N == ND) {
// ND is already in a single-value congruent class
Node* Leader = ND->getLeader();
// Remove ND from the congruent class
Node* P = ND->prev;
N->prev = P;
P->next = N;
// ND : a new single-value congruent class
ND->next = ND;
ND->prev = ND;
ND->rank = 0;
// If leader is removed, need to have a new leader.
if (Leader == ND) {
// P will be the new leader. Also swap ND's color with P's
// so that the original congruent class still have the original
// color (this is important as Dom traversal assumes that the
// color of any congruent class remains unchanged).
int t = P->color;
P->color = ND->color;
ND->color = t;
// New leader
Leader = P;
// If ND is a leaf node, no need to set parent. As we don't
// know if it has any children. A path compression is done
// always to set "Leader' as the new leader, so that all nodes
// within a same congruent class remains in the same rooted tree.
N = Leader->next;
Leader->rank = (Leader == N) ? 0 : 1;
while (N != Leader)
N->rank = 0;
N = N->next;
/// SplitInterferencesForBasicBlock - traverses a basic block, splitting any
/// interferences found between registers in the same congruence class. It
/// takes two DenseMaps as arguments that it also updates:
......@@ -200,6 +200,10 @@ class DeSSA : public llvm::FunctionPass {
/// Isolate a PHI.
void isolatePHI(llvm::Instruction*);
// Split node from its existing congurent class, and
// node itself becomes a new single-value congruent class
void splitNode(Node* ND);
/// Traverses a basic block, splitting any interferences found between
/// registers in the same congruence class. It takes two DenseMaps as
/// arguments that it also updates: CurrentDominatingParent, which maps
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment