1 //===-- IndMemRemoval.cpp - Remove indirect allocations and frees ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass finds places where memory allocation functions may escape into
11 // indirect land. Some transforms are much easier (aka possible) only if free
12 // or malloc are not called indirectly.
13 // Thus find places where the address of memory functions are taken and construct
14 // bounce functions with direct calls of those functions.
16 //===----------------------------------------------------------------------===//
18 #define DEBUG_TYPE "indmemrem"
19 #include "llvm/Transforms/IPO.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Module.h"
22 #include "llvm/Instructions.h"
23 #include "llvm/Type.h"
24 #include "llvm/DerivedTypes.h"
25 #include "llvm/ADT/Statistic.h"
26 #include "llvm/Support/Compiler.h"
29 STATISTIC(NumBounceSites
, "Number of sites modified");
30 STATISTIC(NumBounce
, "Number of bounce functions created");
33 class VISIBILITY_HIDDEN IndMemRemPass
: public ModulePass
{
35 static char ID
; // Pass identification, replacement for typeid
36 IndMemRemPass() : ModulePass(&ID
) {}
38 virtual bool runOnModule(Module
&M
);
40 } // end anonymous namespace
42 char IndMemRemPass::ID
= 0;
43 static RegisterPass
<IndMemRemPass
>
44 X("indmemrem","Indirect Malloc and Free Removal");
46 bool IndMemRemPass::runOnModule(Module
&M
) {
47 // In theory, all direct calls of malloc and free should be promoted
48 // to intrinsics. Therefore, this goes through and finds where the
49 // address of free or malloc are taken and replaces those with bounce
50 // functions, ensuring that all malloc and free that might happen
51 // happen through intrinsics.
53 if (Function
* F
= M
.getFunction("free")) {
54 if (F
->isDeclaration() && F
->arg_size() == 1 && !F
->use_empty()) {
55 Function
* FN
= Function::Create(F
->getFunctionType(),
56 GlobalValue::LinkOnceAnyLinkage
,
57 "free_llvm_bounce", &M
);
58 BasicBlock
* bb
= BasicBlock::Create("entry",FN
);
59 Instruction
* R
= ReturnInst::Create(bb
);
60 new FreeInst(FN
->arg_begin(), R
);
62 NumBounceSites
+= F
->getNumUses();
63 F
->replaceAllUsesWith(FN
);
67 if (Function
* F
= M
.getFunction("malloc")) {
68 if (F
->isDeclaration() && F
->arg_size() == 1 && !F
->use_empty()) {
69 Function
* FN
= Function::Create(F
->getFunctionType(),
70 GlobalValue::LinkOnceAnyLinkage
,
71 "malloc_llvm_bounce", &M
);
72 FN
->setDoesNotAlias(0);
73 BasicBlock
* bb
= BasicBlock::Create("entry",FN
);
74 Instruction
* c
= CastInst::CreateIntegerCast(
75 FN
->arg_begin(), Type::Int32Ty
, false, "c", bb
);
76 Instruction
* a
= new MallocInst(Type::Int8Ty
, c
, "m", bb
);
77 ReturnInst::Create(a
, bb
);
79 NumBounceSites
+= F
->getNumUses();
80 F
->replaceAllUsesWith(FN
);
87 ModulePass
*llvm::createIndMemRemPass() {
88 return new IndMemRemPass();