blob: c68a4d3b24942ac7a245dd737fa5fe7a97138aaf [file] [log] [blame]
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +00001//===-- IndMemRemoval.cpp - Remove indirect allocations and frees ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
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.
15//
16//===----------------------------------------------------------------------===//
17
Chris Lattner1631bcb2006-12-19 22:09:18 +000018#define DEBUG_TYPE "indmemrem"
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000019#include "llvm/Transforms/IPO.h"
20#include "llvm/Pass.h"
21#include "llvm/Module.h"
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000022#include "llvm/Instructions.h"
23#include "llvm/Type.h"
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000024#include "llvm/ADT/Statistic.h"
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000025using namespace llvm;
26
Chris Lattner1631bcb2006-12-19 22:09:18 +000027STATISTIC(NumBounceSites, "Number of sites modified");
28STATISTIC(NumBounce , "Number of bounce functions created");
29
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000030namespace {
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000031 class IndMemRemPass : public ModulePass {
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000032 public:
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000033 virtual bool runOnModule(Module &M);
34 };
Chris Lattnerc2d3d312006-08-27 22:42:52 +000035 RegisterPass<IndMemRemPass> X("indmemrem","Indirect Malloc and Free Removal");
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000036} // end anonymous namespace
37
38
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000039bool IndMemRemPass::runOnModule(Module &M) {
40 //in Theory, all direct calls of malloc and free should be promoted
41 //to intrinsics. Therefor, this goes through and finds where the
42 //address of free or malloc are taken and replaces those with bounce
43 //functions, ensuring that all malloc and free that might happen
Andrew Lenharth92cf71f2006-04-13 13:43:31 +000044 //happen through intrinsics.
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000045 bool changed = false;
46 if (Function* F = M.getNamedFunction("free")) {
47 assert(F->isExternal() && "free not external?");
Andrew Lenharth92cf71f2006-04-13 13:43:31 +000048 if (!F->use_empty()) {
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000049 Function* FN = new Function(F->getFunctionType(),
50 GlobalValue::LinkOnceLinkage,
51 "free_llvm_bounce", &M);
52 BasicBlock* bb = new BasicBlock("entry",FN);
53 Instruction* R = new ReturnInst(bb);
54 new FreeInst(FN->arg_begin(), R);
55 ++NumBounce;
56 NumBounceSites += F->getNumUses();
57 F->replaceAllUsesWith(FN);
58 changed = true;
59 }
60 }
61 if (Function* F = M.getNamedFunction("malloc")) {
62 assert(F->isExternal() && "malloc not external?");
Andrew Lenharth92cf71f2006-04-13 13:43:31 +000063 if (!F->use_empty()) {
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000064 Function* FN = new Function(F->getFunctionType(),
65 GlobalValue::LinkOnceLinkage,
66 "malloc_llvm_bounce", &M);
67 BasicBlock* bb = new BasicBlock("entry",FN);
Reid Spencerbfe26ff2006-12-13 00:50:17 +000068 Instruction* c = CastInst::createIntegerCast(
Reid Spencerc635f472006-12-31 05:48:39 +000069 FN->arg_begin(), Type::Int32Ty, false, "c", bb);
70 Instruction* a = new MallocInst(Type::Int8Ty, c, "m", bb);
Reid Spencerde46e482006-11-02 20:25:50 +000071 new ReturnInst(a, bb);
Andrew Lenhartha9cdcca2006-04-10 19:26:09 +000072 ++NumBounce;
73 NumBounceSites += F->getNumUses();
74 F->replaceAllUsesWith(FN);
75 changed = true;
76 }
77 }
78 return changed;
79}
80
81ModulePass *llvm::createIndMemRemPass() {
82 return new IndMemRemPass();
83}