Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Unified Diff: lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp

Issue 14617017: Adding a pass - RewritePNaClLibraryCalls, that replaces known library calls with stable bitcode int… (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
diff --git a/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp b/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..76de0ef16d05375f9037d4e6720091873d0dc58c
--- /dev/null
+++ b/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
@@ -0,0 +1,140 @@
+//===- RewritePNaClLibraryCalls.cpp - PNaCl library calls to intrinsics ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass replaces calls to known library functions by calls to intrinsics
Mark Seaborn 2013/05/10 16:34:36 'by' -> 'with'
eliben 2013/05/10 17:00:51 Done.
+// that are part of the PNaCl stable bitcode ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/NaCl.h"
+
+using namespace llvm;
+
+namespace {
+ class RewritePNaClLibraryCalls : public ModulePass {
Mark Seaborn 2013/05/10 16:34:36 Maybe comment why this is a ModulePass? Does it n
eliben 2013/05/10 17:00:51 Done.
+ public:
+ static char ID;
+ RewritePNaClLibraryCalls() : ModulePass(ID) {
+ initializeExpandTlsPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual bool runOnModule(Module &M);
+ private:
+ /// Rewrite the given \p Call to setjmp
+ void rewriteSetjmp(CallInst *Call);
+ /// Rewrite the given \p Call to longjmp
+ void rewriteLongjmp(CallInst *Call);
+
+ Module *TheModule;
+ };
+}
+
+char RewritePNaClLibraryCalls::ID = 0;
+INITIALIZE_PASS(RewritePNaClLibraryCalls, "rewrite-pnacl-library-calls",
+ "Rewrite PNaCl library calls to stable intrinsics",
+ false, false)
+
+bool RewritePNaClLibraryCalls::runOnModule(Module &M) {
+ TheModule = &M;
+ bool Changed = false;
+
+ for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
Mark Seaborn 2013/05/10 16:34:36 Iterating through all calls is inefficient. It wo
eliben 2013/05/10 17:00:51 Yeah, although given a larger amount of functions
eliben 2013/05/10 23:39:52 Done.
+ for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) {
+ for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
+ Instruction *Inst = I++;
+
+ if (CallInst *Call = dyn_cast<CallInst>(Inst)) {
+ StringRef CalleeName = Call->getCalledFunction()->getName();
Mark Seaborn 2013/05/10 16:34:36 I think you need to check the linkage type too. T
eliben 2013/05/10 23:39:52 Done.
+
+ if (CalleeName == "setjmp") {
+ rewriteSetjmp(Call);
+ Changed = true;
+ } else if (CalleeName == "longjmp") {
+ rewriteLongjmp(Call);
+ Changed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return Changed;
+}
+
+void RewritePNaClLibraryCalls::rewriteSetjmp(CallInst *Call) {
+ FunctionType *FTy = Call->getCalledFunction()->getFunctionType();
+
+ // Sanity check on the setjmp call.
+ if (FTy->getNumParams() != 1 ||
+ !FTy->getReturnType()->isIntegerTy() ||
+ !FTy->getParamType(0)->isPointerTy()) {
+ report_fatal_error(Twine("Wrong signature of function ") +
+ Call->getCalledFunction()->getName());
+ }
+ const DebugLoc &DLoc = Call->getDebugLoc();
+
+ // Cast the jmp_buf argument to i8* since this is what the intrinsic expects.
+ Type *I8Ptr = Type::getInt8Ty(TheModule->getContext())->getPointerTo();
Mark Seaborn 2013/05/10 16:34:36 You could use: NaclSetjmpFunc->getFunctionType()->
+ BitCastInst *JmpBufCast = new BitCastInst(Call->getArgOperand(0), I8Ptr,
+ "jmp_buf_i8", Call);
+ JmpBufCast->setDebugLoc(DLoc);
+
+ // Find the intrinsic function and call it.
+ Function *NaclSetjmpFunc = Intrinsic::getDeclaration(TheModule,
Mark Seaborn 2013/05/10 16:34:36 Maybe "Nacl" -> "NaCl"?
eliben 2013/05/10 23:39:52 Done.
+ Intrinsic::nacl_setjmp);
+ SmallVector<Value *, 2> Args;
+ Args.push_back(JmpBufCast);
+ CallInst *NaclSetjmpCall = CallInst::Create(NaclSetjmpFunc, Args, "", Call);
+ NaclSetjmpCall->setDebugLoc(DLoc);
Mark Seaborn 2013/05/10 16:34:36 Use takeName() too
eliben 2013/05/10 23:39:52 Done.
+
+ // Replace the original call.
+ Call->replaceAllUsesWith(NaclSetjmpCall);
+ Call->eraseFromParent();
+}
+
+void RewritePNaClLibraryCalls::rewriteLongjmp(CallInst *Call) {
+ FunctionType *FTy = Call->getCalledFunction()->getFunctionType();
+
+ // Sanity check on the longjmp call.
+ if (FTy->getNumParams() != 2 ||
+ !FTy->getReturnType()->isVoidTy() ||
+ !FTy->getParamType(0)->isPointerTy()) {
+ report_fatal_error(Twine("Wrong signature of function ") +
+ Call->getCalledFunction()->getName());
+ }
+ const DebugLoc &DLoc = Call->getDebugLoc();
+
+ // Cast the jmp_buf argument to i8* since this is what the intrinsic expects.
+ Type *I8Ptr = Type::getInt8Ty(TheModule->getContext())->getPointerTo();
+ BitCastInst *JmpBufCast = new BitCastInst(Call->getArgOperand(0), I8Ptr,
+ "jmp_buf_i8", Call);
+ JmpBufCast->setDebugLoc(DLoc);
+
+ // Find the intrinsic function and call it.
+ Function *NaclLongjmpFunc = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::nacl_longjmp);
Mark Seaborn 2013/05/10 16:34:36 Line >80 chars
eliben 2013/05/10 23:39:52 Done.
+ SmallVector<Value *, 2> Args;
+ Args.push_back(JmpBufCast);
+ Args.push_back(Call->getArgOperand(1));
+ CallInst *NaclLongjmpCall = CallInst::Create(NaclLongjmpFunc, Args, "", Call);
+ NaclLongjmpCall->setDebugLoc(DLoc);
+
+ // Remove the original call. There's no need for RAUW because longjmp
+ // returns void.
+ Call->eraseFromParent();
+}
+
+ModulePass *llvm::createRewritePNaClLibraryCallsPass() {
+ return new RewritePNaClLibraryCalls();
+}

Powered by Google App Engine
This is Rietveld 408576698