summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Transforms/Utils/OrderedInstructions.h51
-rw-r--r--llvm/lib/Transforms/Utils/CMakeLists.txt1
-rw-r--r--llvm/lib/Transforms/Utils/OrderedInstructions.cpp33
-rw-r--r--llvm/unittests/Transforms/Utils/CMakeLists.txt1
-rw-r--r--llvm/unittests/Transforms/Utils/OrderedInstructions.cpp65
5 files changed, 151 insertions, 0 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h b/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h
new file mode 100644
index 00000000000..e043ff39a99
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h
@@ -0,0 +1,51 @@
+//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an efficient way to check for dominance relation between 2
+// instructions.
+//
+// This interface dispatches to appropriate dominance check given 2
+// instructions, i.e. in case the instructions are in the same basic block,
+// OrderedBasicBlock (with instruction numbering and caching) are used.
+// Otherwise, dominator tree is used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
+#define LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/OrderedBasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Operator.h"
+
+namespace llvm {
+
+class OrderedInstructions {
+ /// Used to check dominance for instructions in same basic block.
+ mutable DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>>
+ OBBMap;
+
+ /// The dominator tree of the parent function.
+ DominatorTree *DT;
+
+public:
+ /// Constructor.
+ OrderedInstructions(DominatorTree *DT) : DT(DT) {}
+
+ /// Return true if first instruction dominates the second.
+ bool dominates(const Instruction *, const Instruction *) const;
+
+ /// Invalidate the OrderedBasicBlock cache when its basic block changes.
+ void invalidateBlock(BasicBlock *BB) { OBBMap.erase(BB); }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index 7a21c03da22..83bc05d0311 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -37,6 +37,7 @@ add_llvm_library(LLVMTransformUtils
MetaRenamer.cpp
ModuleUtils.cpp
NameAnonGlobals.cpp
+ OrderedInstructions.cpp
PredicateInfo.cpp
PromoteMemoryToRegister.cpp
StripGCRelocates.cpp
diff --git a/llvm/lib/Transforms/Utils/OrderedInstructions.cpp b/llvm/lib/Transforms/Utils/OrderedInstructions.cpp
new file mode 100644
index 00000000000..2e67e0def5b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/OrderedInstructions.cpp
@@ -0,0 +1,33 @@
+//===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utility to check dominance relation of 2 instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/OrderedInstructions.h"
+using namespace llvm;
+
+/// Given 2 instructions, use OrderedBasicBlock to 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 {
+ const BasicBlock *IBB = InstA->getParent();
+ // Use ordered basic block to do dominance check in case the 2 instructions
+ // are in the same basic block.
+ if (IBB == InstB->getParent()) {
+ auto OBB = OBBMap.find(IBB);
+ if (OBB == OBBMap.end())
+ OBB = OBBMap.insert({IBB, make_unique<OrderedBasicBlock>(IBB)}).first;
+ return OBB->second->dominates(InstA, InstB);
+ } else {
+ return DT->dominates(InstA->getParent(), InstB->getParent());
+ }
+}
diff --git a/llvm/unittests/Transforms/Utils/CMakeLists.txt b/llvm/unittests/Transforms/Utils/CMakeLists.txt
index 0fc19ef09fb..475c365dddc 100644
--- a/llvm/unittests/Transforms/Utils/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Utils/CMakeLists.txt
@@ -11,5 +11,6 @@ add_llvm_unittest(UtilsTests
FunctionComparator.cpp
IntegerDivision.cpp
Local.cpp
+ OrderedInstructions.cpp
ValueMapperTest.cpp
)
diff --git a/llvm/unittests/Transforms/Utils/OrderedInstructions.cpp b/llvm/unittests/Transforms/Utils/OrderedInstructions.cpp
new file mode 100644
index 00000000000..1d6df172294
--- /dev/null
+++ b/llvm/unittests/Transforms/Utils/OrderedInstructions.cpp
@@ -0,0 +1,65 @@
+//===- OrderedInstructions.cpp - Unit tests for OrderedInstructions ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/OrderedInstructions.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+/// Check intra-basicblock and inter-basicblock dominance using
+/// OrderedInstruction.
+TEST(OrderedInstructionsTest, DominanceTest) {
+ LLVMContext Ctx;
+ Module M("test", Ctx);
+ IRBuilder<> B(Ctx);
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
+ Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+
+ // Create the function as follow and check for dominance relation.
+ //
+ // test():
+ // bbx:
+ // loadx;
+ // loady;
+ // bby:
+ // loadz;
+ // return;
+ //
+ // More specifically, check for loadx -> (dominates) loady,
+ // loady -> loadx and loady -> loadz.
+ //
+ // Create BBX with 2 loads.
+ BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
+ B.SetInsertPoint(BBX);
+ Argument *PointerArg = &*F->arg_begin();
+ LoadInst *LoadInstX = B.CreateLoad(PointerArg);
+ LoadInst *LoadInstY = B.CreateLoad(PointerArg);
+
+ // Create BBY with 1 load.
+ BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
+ B.SetInsertPoint(BBY);
+ LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
+ B.CreateRet(LoadInstZ);
+ std::unique_ptr<DominatorTree> DT(new DominatorTree(*F));
+ OrderedInstructions OI(&*DT);
+
+ // Intra-BB dominance test.
+ EXPECT_TRUE(OI.dominates(LoadInstX, LoadInstY));
+ EXPECT_FALSE(OI.dominates(LoadInstY, LoadInstX));
+
+ // Inter-BB dominance test.
+ EXPECT_TRUE(OI.dominates(LoadInstY, LoadInstZ));
+}
OpenPOWER on IntegriCloud