Index: lib/Transforms/NaCl/ExpandUtils.cpp |
diff --git a/lib/Transforms/NaCl/ExpandUtils.cpp b/lib/Transforms/NaCl/ExpandUtils.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f825f3fce3bd06819ddacca8150d6d42df3676b0 |
--- /dev/null |
+++ b/lib/Transforms/NaCl/ExpandUtils.cpp |
@@ -0,0 +1,58 @@ |
+//===-- ExpandUtils.cpp - Helper functions for expansion passes -----------===// |
+// |
+// The LLVM Compiler Infrastructure |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#include "llvm/IR/BasicBlock.h" |
+#include "llvm/IR/Constants.h" |
+#include "llvm/IR/Function.h" |
+#include "llvm/IR/Instructions.h" |
+#include "llvm/IR/Module.h" |
+#include "llvm/Support/raw_ostream.h" |
+#include "llvm/Transforms/NaCl.h" |
+ |
+using namespace llvm; |
+ |
+Instruction *llvm::PhiSafeInsertPt(Use *U) { |
+ Instruction *InsertPt = cast<Instruction>(U->getUser()); |
+ if (PHINode *PN = dyn_cast<PHINode>(InsertPt)) { |
+ // We cannot insert instructions before a PHI node, so insert |
+ // before the incoming block's terminator. This could be |
+ // suboptimal if the terminator is a conditional. |
+ InsertPt = PN->getIncomingBlock(*U)->getTerminator(); |
+ } |
+ return InsertPt; |
+} |
+ |
+void llvm::PhiSafeReplaceUses(Use *U, Value *NewVal) { |
+ User *UR = U->getUser(); |
+ if (PHINode *PN = dyn_cast<PHINode>(UR)) { |
+ // A PHI node can have multiple incoming edges from the same |
+ // block, in which case all these edges must have the same |
+ // incoming value. |
+ BasicBlock *BB = PN->getIncomingBlock(*U); |
+ for (unsigned I = 0; I < PN->getNumIncomingValues(); ++I) { |
+ if (PN->getIncomingBlock(I) == BB) |
+ PN->setIncomingValue(I, NewVal); |
+ } |
+ } else { |
+ UR->replaceUsesOfWith(U->get(), NewVal); |
+ } |
+} |
+ |
+Function *llvm::RecreateFunction(Function *Func, FunctionType *NewType) { |
+ Function *NewFunc = Function::Create(NewType, Func->getLinkage()); |
+ NewFunc->copyAttributesFrom(Func); |
+ Func->getParent()->getFunctionList().insert(Func, NewFunc); |
+ NewFunc->takeName(Func); |
+ NewFunc->getBasicBlockList().splice(NewFunc->begin(), |
+ Func->getBasicBlockList()); |
+ Func->replaceAllUsesWith( |
+ ConstantExpr::getBitCast(NewFunc, |
+ Func->getFunctionType()->getPointerTo())); |
+ return NewFunc; |
+} |