[LLVMdev] BlockAddress instruction is copied instead of cloned during module link?
Yuri
yuri at rawbw.com
Sun Jun 17 04:47:03 PDT 2012
I have a module having the blockaddress instruction.
When I link it into another module and delete the original, blockaddress
disappears and is replaced by inttoptr (i32 1 to i8*).
Please compile and run the attached program to see the demo of this
problem.
Right after linking modules, blockaddress still exists:
@switch.bbs = internal global [3 x i8*] [i8* blockaddress(@my_func,
%switch.body.begin), i8* blockaddress(@my_func, %switch.body.begin1),
i8* inttoptr (i32 1 to i8*)]
But once the original module is deleted, the same line in destination is
replaced by the one with inttoptr:
@switch.bbs = internal global [3 x i8*] [i8* inttoptr (i32 1 to i8*),
i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
So it looks like BlockAddress instruction is copied instead of cloned
into the destination module?
rev.158596
Yuri
--- testcase.cpp ---
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Constants.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Function.h>
#include <llvm/CallingConv.h>
#include <llvm/BasicBlock.h>
#include <llvm/Instructions.h>
#include <llvm/InlineAsm.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MathExtras.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Linker.h>
#include <algorithm>
using namespace llvm;
Module* makeLLVMModule();
int main(int argc, char**argv) {
Module* Mod = makeLLVMModule();
verifyModule(*Mod, PrintMessageAction);
PassManager PM;
PM.add(createPrintModulePass(&outs()));
printf("===original==\n");
PM.run(*Mod);
Module* ModL = new Module("xL.ll", getGlobalContext());
llvm::Linker::LinkModules(ModL, Mod, Linker::PreserveSource, 0);
printf("===linked: before original delete==\n");
PM.run(*ModL);
delete Mod;
printf("===linked: after original delete==\n");
PM.run(*ModL);
return 0;
}
Module* makeLLVMModule() {
// Module Construction
Module* mod = new Module("x.ll", getGlobalContext());
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
mod->setTargetTriple("x86_64-unknown-freebsd8.2");
// Type Definitions
PointerType* PointerTy_1 =
PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
ArrayType* ArrayTy_0 = ArrayType::get(PointerTy_1, 3);
PointerType* PointerTy_2 = PointerType::get(ArrayTy_0, 0);
std::vector<Type*>FuncTy_3_args;
FuncTy_3_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_3 = FunctionType::get(
/*Result=*/PointerTy_1,
/*Params=*/FuncTy_3_args,
/*isVarArg=*/false);
PointerType* PointerTy_4 = PointerType::get(PointerTy_1, 0);
// Function Declarations
Function* func_my_func = mod->getFunction("my_func");
if (!func_my_func) {
func_my_func = Function::Create(
/*Type=*/FuncTy_3,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"my_func", mod);
func_my_func->setCallingConv(CallingConv::C);
}
AttrListPtr func_my_func_PAL;
func_my_func->setAttributes(func_my_func_PAL);
BasicBlock* label_issue_top = BasicBlock::Create(mod->getContext(),
"issue.top",func_my_func,0);
BasicBlock* label_switch_body_begin =
BasicBlock::Create(mod->getContext(), "switch.body.begin",func_my_func,0);
BasicBlock* label_switch_body_begin1 =
BasicBlock::Create(mod->getContext(), "switch.body.begin1",func_my_func,0);
BasicBlock* label_switch_end = BasicBlock::Create(mod->getContext(),
"switch.end",func_my_func,0);
// Global Variable Declarations
GlobalVariable* gvar_array_switch_bbs = new
GlobalVariable(/*Module=*/*mod,
/*Type=*/ArrayTy_0,
/*isConstant=*/false,
/*Linkage=*/GlobalValue::InternalLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/"switch.bbs");
// Constant Definitions
std::vector<Constant*> const_array_5_elems;
Constant* const_ptr_6 = BlockAddress::get(label_switch_body_begin);
const_array_5_elems.push_back(const_ptr_6);
Constant* const_ptr_7 = BlI have a module having the blockaddress
instruction.
When I link it into another module and delete the original, blockaddress
disappears and is replaced by inttoptr (i32 1 to i8*).
Please compile and run the attached program to see the demo of this
problem.
Right after linking modules, blockaddress still exists:
@switch.bbs = internal global [3 x i8*] [i8* blockaddress(@my_func,
%switch.body.begin), i8* blockaddress(@my_func, %switch.body.begin1),
i8* inttoptr (i32 1 to i8*)]
But once the original module is deleted, the same line in destination is
replaced by the one with inttoptr:
@switch.bbs = internal global [3 x i8*] [i8* inttoptr (i32 1 to i8*),
i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
So it looks like BlockAddress instruction is copied instead of cloned
into the destination module?
rev.158596
Yuri
--- testcase.cpp ---
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Constants.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Function.h>
#include <llvm/CallingConv.h>
#include <llvm/BasicBlock.h>
#include <llvm/Instructions.h>
#include <llvm/InlineAsm.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MathExtras.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Linker.h>
#include <algorithm>
using namespace llvm;
Module* makeLLVMModule();
int main(int argc, char**argv) {
Module* Mod = makeLLVMModule();
verifyModule(*Mod, PrintMessageAction);
PassManager PM;
PM.add(createPrintModulePass(&outs()));
printf("===original==\n");
PM.run(*Mod);
Module* ModL = new Module("xL.ll", getGlobalContext());
llvm::Linker::LinkModules(ModL, Mod, Linker::PreserveSource, 0);
printf("===linked: before original delete==\n");
PM.run(*ModL);
delete Mod;
printf("===linked: after original delete==\n");
PM.run(*ModL);
return 0;
}
Module* makeLLVMModule() {
// Module Construction
Module* mod = new Module("x.ll", getGlobalContext());
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
mod->setTargetTriple("x86_64-unknown-freebsd8.2");
// Type Definitions
PointerType* PointerTy_1 =
PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
ArrayType* ArrayTy_0 = ArrayType::get(PointerTy_1, 3);
PointerType* PointerTy_2 = PointerType::get(ArrayTy_0, 0);
std::vector<Type*>FuncTy_3_args;
FuncTy_3_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_3 = FunctionType::get(
/*Result=*/PointerTy_1,
/*Params=*/FuncTy_3_args,
/*isVarArg=*/false);
PointerType* PointerTy_4 = PointerType::get(PointerTy_1, 0);
// Function Declarations
Function* func_my_func = mod->getFunction("my_func");
if (!func_my_func) {
func_my_func = Function::Create(
/*Type=*/FuncTy_3,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"my_func", mod);
func_my_func->setCallingConv(CallingConv::C);
}
AttrListPtr func_my_func_PAL;
func_my_func->setAttributes(func_my_func_PAL);
BasicBlock* label_issue_top = BasicBlock::Create(mod->getContext(),
"issue.top",func_my_func,0);
BasicBlock* label_switch_body_begin =
BasicBlock::Create(mod->getContext(), "switch.body.begin",func_my_func,0);
BasicBlock* label_switch_body_begin1 =
BasicBlock::Create(mod->getContext(), "switch.body.begin1",func_my_func,0);
BasicBlock* label_switch_end = BasicBlock::Create(mod->getContext(),
"switch.end",func_my_func,0);
// Global Variable Declarations
GlobalVariable* gvar_array_switch_bbs = new
GlobalVariable(/*Module=*/*mod,
/*Type=*/ArrayTy_0,
/*isConstant=*/false,
/*Linkage=*/GlobalValue::InternalLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/"switch.bbs");
// Constant Definitions
std::vector<Constant*> const_array_5_elems;
Constant* const_ptr_6 = BlockAddress::get(label_switch_body_begin);
const_array_5_elems.push_back(const_ptr_6);
Constant* const_ptr_7 = BlockAddress::get(label_switch_body_begin1);
const_array_5_elems.push_back(const_ptr_7);
ConstantInt* const_int32_9 = ConstantInt::get(mod->getContext(),
APInt(32, StringRef("1"), 10));
Constant* const_ptr_8 = ConstantExpr::getCast(Instruction::IntToPtr,
const_int32_9, PointerTy_1);
const_array_5_elems.push_back(const_ptr_8);
Constant* const_array_5 = ConstantArray::get(ArrayTy_0,
const_array_5_elems);
ConstantInt* const_int32_10 = ConstantInt::get(mod->getContext(),
APInt(32, StringRef("0"), 10));
ConstantPointerNull* const_ptr_11 =
ConstantPointerNull::get(PointerTy_1);
// Global Variable Definitions
gvar_array_switch_bbs->setInitializer(const_array_5);
// Function Definitions
// Function: my_func (func_my_func)
{
Function::arg_iterator args = func_my_func->arg_begin();
Value* int32_12 = args++;
// Block issue.top (label_issue_top)
std::vector<Value*> ptr_switch_gep_indices;
ptr_switch_gep_indices.push_back(const_int32_10);
ptr_switch_gep_indices.push_back(int32_12);
Instruction* ptr_switch_gep =
GetElementPtrInst::Create(gvar_array_switch_bbs, ptr_switch_gep_indices,
"switch.gep", label_issue_top);
LoadInst* ptr_switch_load = new LoadInst(ptr_switch_gep,
"switch.load", false, label_issue_top);
ReturnInst::Create(mod->getContext(), ptr_switch_load, label_issue_top);
// Block switch.body.begin (label_switch_body_begin)
BranchInst::Create(label_switch_end, label_switch_body_begin);
// Block switch.body.begin1 (label_switch_body_begin1)
BranchInst::Create(label_switch_end, label_switch_body_begin1);
// Block switch.end (label_switch_end)
ReturnInst::Create(mod->getContext(), const_ptr_11, label_switch_end);
}
return mod;
}
ockAddress::get(label_switch_body_begin1);
const_array_5_elems.push_back(const_ptr_7);
ConstantInt* const_int32_9 = ConstantInt::get(mod->getContext(),
APInt(32, StringRef("1"), 10));
Constant* const_ptr_8 = ConstantExpr::getCast(Instruction::IntToPtr,
const_int32_9, PointerTy_1);
const_array_5_elems.push_back(const_ptr_8);
Constant* const_array_5 = ConstantArray::get(ArrayTy_0,
const_array_5_elems);
ConstantInt* const_int32_10 = ConstantInt::get(mod->getContext(),
APInt(32, StringRef("0"), 10));
ConstantPointerNull* const_ptr_11 =
ConstantPointerNull::get(PointerTy_1);
// Global Variable Definitions
gvar_array_switch_bbs->setInitializer(const_array_5);
// Function Definitions
// Function: my_func (func_my_func)
{
Function::arg_iterator args = func_my_func->arg_begin();
Value* int32_12 = args++;
// Block issue.top (label_issue_top)
std::vector<Value*> ptr_switch_gep_indices;
ptr_switch_gep_indices.push_back(const_int32_10);
ptr_switch_gep_indices.push_back(int32_12);
Instruction* ptr_switch_gep =
GetElementPtrInst::Create(gvar_array_switch_bbs, ptr_switch_gep_indices,
"switch.gep", label_issue_top);
LoadInst* ptr_switch_load = new LoadInst(ptr_switch_gep,
"switch.load", false, label_issue_top);
ReturnInst::Create(mod->getContext(), ptr_switch_load, label_issue_top);
// Block switch.body.begin (label_switch_body_begin)
BranchInst::Create(label_switch_end, label_switch_body_begin);
// Block switch.body.begin1 (label_switch_body_begin1)
BranchInst::Create(label_switch_end, label_switch_body_begin1);
// Block switch.end (label_switch_end)
ReturnInst::Create(mod->getContext(), const_ptr_11, label_switch_end);
}
return mod;
}
More information about the llvm-dev
mailing list