code motion Summary: Currently isSafeToMoveBefore uses DFS numbering for determining the relative position of instruction and insert point which is not always correct. This PR proposes the use of Dominator Tree depth for the same. If a node is at a higher level than the insert point then it is safe to say that we want to move in the forward direction. Authored By: RithikSharma Reviewer: Whitney, nikic, bmahjour, etiotto, fhahn Reviewed By: Whitney Subscribers: fhahn, hiraditya, llvm-commits Tag: LLVM Differential Revision: https://reviews.llvm.org/D80084
58 lines
2.3 KiB
C++
58 lines
2.3 KiB
C++
//===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines utility to check dominance relation of 2 instructions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/OrderedInstructions.h"
|
|
using namespace llvm;
|
|
|
|
bool OrderedInstructions::localDominates(const Instruction *InstA,
|
|
const Instruction *InstB) const {
|
|
assert(InstA->getParent() == InstB->getParent() &&
|
|
"Instructions must be in the same basic block");
|
|
|
|
return InstA->comesBefore(InstB);
|
|
}
|
|
|
|
/// Given 2 instructions, check for dominance relation if the instructions are
|
|
/// in the same basic block. Otherwise, use dominator tree.
|
|
bool OrderedInstructions::dominates(const Instruction *InstA,
|
|
const Instruction *InstB) const {
|
|
// Use ordered basic block to do dominance check in case the 2 instructions
|
|
// are in the same basic block.
|
|
if (InstA->getParent() == InstB->getParent())
|
|
return localDominates(InstA, InstB);
|
|
return DT->dominates(InstA->getParent(), InstB->getParent());
|
|
}
|
|
|
|
bool OrderedInstructions::dfsBefore(const Instruction *InstA,
|
|
const Instruction *InstB) const {
|
|
// Use ordered basic block in case the 2 instructions are in the same basic
|
|
// block.
|
|
if (InstA->getParent() == InstB->getParent())
|
|
return localDominates(InstA, InstB);
|
|
|
|
DomTreeNode *DA = DT->getNode(InstA->getParent());
|
|
DomTreeNode *DB = DT->getNode(InstB->getParent());
|
|
return DA->getDFSNumIn() < DB->getDFSNumIn();
|
|
}
|
|
|
|
bool OrderedInstructions::domTreeLevelBefore(const Instruction *InstA,
|
|
const Instruction *InstB) const {
|
|
// Use ordered basic block in case the 2 instructions are in the same basic
|
|
// block.
|
|
if (InstA->getParent() == InstB->getParent())
|
|
return localDominates(InstA, InstB);
|
|
|
|
DomTreeNode *DA = DT->getNode(InstA->getParent());
|
|
DomTreeNode *DB = DT->getNode(InstB->getParent());
|
|
return DA->getLevel() < DB->getLevel();
|
|
}
|