We do not need to keep `malloc` and `free` around since they are
replaced by `polly_{malloc,free}Managed.`
llvm-svn: 310504
147 lines
5.2 KiB
C++
147 lines
5.2 KiB
C++
//===------ ManagedMemoryRewrite.cpp - Rewrite global & malloc'd memory.
|
|
//---===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Take a module and rewrite:
|
|
// 1. `malloc` -> `polly_mallocManaged`
|
|
// 2. `free` -> `polly_freeManaged`
|
|
// 3. global arrays with initializers -> global arrays that are initialized
|
|
// with a constructor call to
|
|
// `polly_mallocManaged`.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "polly/CodeGen/CodeGeneration.h"
|
|
#include "polly/CodeGen/IslAst.h"
|
|
#include "polly/CodeGen/IslNodeBuilder.h"
|
|
#include "polly/CodeGen/PPCGCodeGeneration.h"
|
|
#include "polly/CodeGen/Utils.h"
|
|
#include "polly/DependenceInfo.h"
|
|
#include "polly/LinkAllPasses.h"
|
|
#include "polly/Options.h"
|
|
#include "polly/ScopDetection.h"
|
|
#include "polly/ScopInfo.h"
|
|
#include "polly/Support/SCEVValidator.h"
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
|
#include "llvm/Analysis/GlobalsModRef.h"
|
|
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
#include "llvm/IR/LegacyPassManager.h"
|
|
#include "llvm/IR/Verifier.h"
|
|
#include "llvm/IRReader/IRReader.h"
|
|
#include "llvm/Linker/Linker.h"
|
|
#include "llvm/Support/TargetRegistry.h"
|
|
#include "llvm/Support/TargetSelect.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
namespace {
|
|
|
|
static llvm::Function *GetOrCreatePollyMallocManaged(Module &M) {
|
|
// TODO: should I allow this pass to be a standalone pass that
|
|
// doesn't care if PollyManagedMemory is enabled or not?
|
|
assert(PollyManagedMemory &&
|
|
"One should only rewrite malloc & free to"
|
|
"polly_{malloc,free}Managed with managed memory enabled.");
|
|
const char *Name = "polly_mallocManaged";
|
|
Function *F = M.getFunction(Name);
|
|
|
|
// If F is not available, declare it.
|
|
if (!F) {
|
|
GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
|
|
PollyIRBuilder Builder(M.getContext());
|
|
// TODO: How do I get `size_t`? I assume from DataLayout?
|
|
FunctionType *Ty = FunctionType::get(Builder.getInt8PtrTy(),
|
|
{Builder.getInt64Ty()}, false);
|
|
F = Function::Create(Ty, Linkage, Name, &M);
|
|
}
|
|
|
|
return F;
|
|
}
|
|
|
|
static llvm::Function *GetOrCreatePollyFreeManaged(Module &M) {
|
|
// TODO: should I allow this pass to be a standalone pass that
|
|
// doesn't care if PollyManagedMemory is enabled or not?
|
|
assert(PollyManagedMemory &&
|
|
"One should only rewrite malloc & free to"
|
|
"polly_{malloc,free}Managed with managed memory enabled.");
|
|
const char *Name = "polly_freeManaged";
|
|
Function *F = M.getFunction(Name);
|
|
|
|
// If F is not available, declare it.
|
|
if (!F) {
|
|
GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
|
|
PollyIRBuilder Builder(M.getContext());
|
|
// TODO: How do I get `size_t`? I assume from DataLayout?
|
|
FunctionType *Ty =
|
|
FunctionType::get(Builder.getVoidTy(), {Builder.getInt8PtrTy()}, false);
|
|
F = Function::Create(Ty, Linkage, Name, &M);
|
|
}
|
|
|
|
return F;
|
|
}
|
|
|
|
class ManagedMemoryRewritePass : public ModulePass {
|
|
public:
|
|
static char ID;
|
|
GPUArch Architecture;
|
|
GPURuntime Runtime;
|
|
ManagedMemoryRewritePass() : ModulePass(ID) {}
|
|
virtual bool runOnModule(Module &M) {
|
|
Function *Malloc = M.getFunction("malloc");
|
|
|
|
if (Malloc) {
|
|
Function *PollyMallocManaged = GetOrCreatePollyMallocManaged(M);
|
|
assert(PollyMallocManaged && "unable to create polly_mallocManaged");
|
|
Malloc->replaceAllUsesWith(PollyMallocManaged);
|
|
Malloc->eraseFromParent();
|
|
}
|
|
|
|
Function *Free = M.getFunction("free");
|
|
|
|
if (Free) {
|
|
Function *PollyFreeManaged = GetOrCreatePollyFreeManaged(M);
|
|
assert(PollyFreeManaged && "unable to create polly_freeManaged");
|
|
Free->replaceAllUsesWith(PollyFreeManaged);
|
|
Free->eraseFromParent();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
char ManagedMemoryRewritePass::ID = 42;
|
|
|
|
Pass *polly::createManagedMemoryRewritePassPass(GPUArch Arch,
|
|
GPURuntime Runtime) {
|
|
ManagedMemoryRewritePass *pass = new ManagedMemoryRewritePass();
|
|
pass->Runtime = Runtime;
|
|
pass->Architecture = Arch;
|
|
return pass;
|
|
}
|
|
|
|
INITIALIZE_PASS_BEGIN(
|
|
ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
|
|
"Polly - Rewrite all allocations in heap & data section to managed memory",
|
|
false, false)
|
|
INITIALIZE_PASS_DEPENDENCY(PPCGCodeGeneration);
|
|
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
|
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
|
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
|
|
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
|
|
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
|
|
INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
|
|
INITIALIZE_PASS_END(
|
|
ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
|
|
"Polly - Rewrite all allocations in heap & data section to managed memory",
|
|
false, false)
|