Cleaning up function creation.
This commit is contained in:
parent
a10a05b6f2
commit
385a4ee23b
|
@ -52,6 +52,7 @@ private:
|
||||||
CodegenFunction* GetCodegenFunction(uint32_t address);
|
CodegenFunction* GetCodegenFunction(uint32_t address);
|
||||||
|
|
||||||
void AddImports();
|
void AddImports();
|
||||||
|
llvm::Function* CreateFunctionDefinition(const char* name);
|
||||||
void AddMissingImport(sdb::FunctionSymbol* fn);
|
void AddMissingImport(sdb::FunctionSymbol* fn);
|
||||||
void AddPresentImport(sdb::FunctionSymbol* fn);
|
void AddPresentImport(sdb::FunctionSymbol* fn);
|
||||||
void PrepareFunction(sdb::FunctionSymbol* fn);
|
void PrepareFunction(sdb::FunctionSymbol* fn);
|
||||||
|
|
|
@ -203,7 +203,7 @@ Value* FunctionGenerator::LoadStateValue(uint32_t offset, Type* type,
|
||||||
PointerType* pointerTy = PointerType::getUnqual(type);
|
PointerType* pointerTy = PointerType::getUnqual(type);
|
||||||
Function::arg_iterator args = gen_fn_->arg_begin();
|
Function::arg_iterator args = gen_fn_->arg_begin();
|
||||||
Value* statePtr = args;
|
Value* statePtr = args;
|
||||||
Value* address = builder_->CreateConstInBoundsGEP1_32(
|
Value* address = builder_->CreateConstInBoundsGEP1_64(
|
||||||
statePtr, offset);
|
statePtr, offset);
|
||||||
Value* ptr = builder_->CreatePointerCast(address, pointerTy);
|
Value* ptr = builder_->CreatePointerCast(address, pointerTy);
|
||||||
return builder_->CreateLoad(ptr, name);
|
return builder_->CreateLoad(ptr, name);
|
||||||
|
@ -214,7 +214,7 @@ void FunctionGenerator::StoreStateValue(uint32_t offset, Type* type,
|
||||||
PointerType* pointerTy = PointerType::getUnqual(type);
|
PointerType* pointerTy = PointerType::getUnqual(type);
|
||||||
Function::arg_iterator args = gen_fn_->arg_begin();
|
Function::arg_iterator args = gen_fn_->arg_begin();
|
||||||
Value* statePtr = args;
|
Value* statePtr = args;
|
||||||
Value* address = builder_->CreateConstInBoundsGEP1_32(
|
Value* address = builder_->CreateConstInBoundsGEP1_64(
|
||||||
statePtr, offset);
|
statePtr, offset);
|
||||||
Value* ptr = builder_->CreatePointerCast(address, pointerTy);
|
Value* ptr = builder_->CreatePointerCast(address, pointerTy);
|
||||||
|
|
||||||
|
|
|
@ -132,37 +132,52 @@ ModuleGenerator::CodegenFunction* ModuleGenerator::GetCodegenFunction(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) {
|
Function* ModuleGenerator::CreateFunctionDefinition(const char* name) {
|
||||||
Module* m = gen_module_;
|
Module* m = gen_module_;
|
||||||
LLVMContext& context = m->getContext();
|
LLVMContext& context = m->getContext();
|
||||||
|
|
||||||
AttributeWithIndex awi[] = {
|
|
||||||
//AttributeWithIndex::get(context, 2, Attributes::NoCapture),
|
|
||||||
AttributeWithIndex::get(context,
|
|
||||||
AttributeSet::FunctionIndex, Attribute::NoUnwind),
|
|
||||||
};
|
|
||||||
AttributeSet attrs = AttributeSet::get(context, awi);
|
|
||||||
|
|
||||||
std::vector<Type*> args;
|
std::vector<Type*> args;
|
||||||
args.push_back(PointerType::getUnqual(Type::getInt8Ty(context)));
|
args.push_back(PointerType::getUnqual(Type::getInt8Ty(context)));
|
||||||
Type* return_type = Type::getInt32Ty(context);
|
Type* return_type = Type::getVoidTy(context);
|
||||||
|
|
||||||
FunctionType* ft = FunctionType::get(return_type,
|
FunctionType* ft = FunctionType::get(return_type,
|
||||||
ArrayRef<Type*>(args), false);
|
ArrayRef<Type*>(args), false);
|
||||||
Function* f = cast<Function>(m->getOrInsertFunction(
|
Function* f = cast<Function>(m->getOrInsertFunction(
|
||||||
StringRef(fn->name), ft, attrs));
|
StringRef(name), ft));
|
||||||
f->setCallingConv(CallingConv::C);
|
|
||||||
f->setVisibility(GlobalValue::DefaultVisibility);
|
f->setVisibility(GlobalValue::DefaultVisibility);
|
||||||
|
|
||||||
|
// Indicate that the function will never be unwound with an exception.
|
||||||
|
// If we ever support native exception handling we may need to remove this.
|
||||||
|
f->doesNotThrow();
|
||||||
|
|
||||||
|
// May be worth trying the X86_FastCall, as we only need state in a register.
|
||||||
|
//f->setCallingConv(CallingConv::Fast);
|
||||||
|
f->setCallingConv(CallingConv::C);
|
||||||
|
|
||||||
Function::arg_iterator fn_args = f->arg_begin();
|
Function::arg_iterator fn_args = f->arg_begin();
|
||||||
|
// 'state'
|
||||||
Value* fn_arg = fn_args++;
|
Value* fn_arg = fn_args++;
|
||||||
fn_arg->setName("state");
|
fn_arg->setName("state");
|
||||||
|
f->setDoesNotAlias(1);
|
||||||
|
// 'state' should try to be in a register, if possible.
|
||||||
|
// TODO(benvanik): verify that's a good idea.
|
||||||
|
// f->getArgumentList().begin()->addAttr(
|
||||||
|
// Attribute::get(context, AttrBuilder().addAttribute(Attribute::InReg)));
|
||||||
|
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) {
|
||||||
|
Module *m = gen_module_;
|
||||||
|
LLVMContext& context = m->getContext();
|
||||||
|
|
||||||
|
// Create the function (and setup args/attributes/etc).
|
||||||
|
Function* f = CreateFunctionDefinition(fn->name);
|
||||||
|
|
||||||
// TODO(benvanik): log errors.
|
// TODO(benvanik): log errors.
|
||||||
BasicBlock* block = BasicBlock::Create(context, "entry", f);
|
BasicBlock* block = BasicBlock::Create(context, "entry", f);
|
||||||
IRBuilder<> builder(block);
|
IRBuilder<> builder(block);
|
||||||
Value* tmp = builder.getInt32(0);
|
builder.CreateRetVoid();
|
||||||
builder.CreateRet(tmp);
|
|
||||||
|
|
||||||
OptimizeFunction(m, f);
|
OptimizeFunction(m, f);
|
||||||
|
|
||||||
|
@ -184,35 +199,16 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) {
|
void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) {
|
||||||
Module* m = gen_module_;
|
// Module* m = gen_module_;
|
||||||
LLVMContext& context = m->getContext();
|
// LLVMContext& context = m->getContext();
|
||||||
|
|
||||||
AttributeWithIndex awi[] = {
|
// Create the function (and setup args/attributes/etc).
|
||||||
//AttributeWithIndex::get(context, 2, Attributes::NoCapture),
|
Function* f = CreateFunctionDefinition(fn->name);
|
||||||
AttributeWithIndex::get(context,
|
|
||||||
AttributeSet::FunctionIndex, Attribute::NoUnwind),
|
|
||||||
};
|
|
||||||
AttributeSet attrs = AttributeSet::get(context, awi);
|
|
||||||
|
|
||||||
std::vector<Type*> args;
|
|
||||||
args.push_back(PointerType::getUnqual(Type::getInt8Ty(context)));
|
|
||||||
Type* return_type = Type::getVoidTy(context);
|
|
||||||
|
|
||||||
FunctionType* ft = FunctionType::get(return_type,
|
|
||||||
ArrayRef<Type*>(args), false);
|
|
||||||
XEASSERTNOTNULL(fn->name);
|
|
||||||
Function* f = cast<Function>(
|
|
||||||
m->getOrInsertFunction(StringRef(fn->name), ft, attrs));
|
|
||||||
f->setCallingConv(CallingConv::C);
|
|
||||||
f->setVisibility(GlobalValue::DefaultVisibility);
|
|
||||||
|
|
||||||
Function::arg_iterator fn_args = f->arg_begin();
|
|
||||||
Value* fn_arg = fn_args++;
|
|
||||||
fn_arg->setName("state");
|
|
||||||
|
|
||||||
|
// Setup our codegen wrapper to keep all the pointers together.
|
||||||
CodegenFunction* cgf = new CodegenFunction();
|
CodegenFunction* cgf = new CodegenFunction();
|
||||||
cgf->symbol = fn;
|
cgf->symbol = fn;
|
||||||
cgf->function_type = ft;
|
cgf->function_type = f->getFunctionType();
|
||||||
cgf->function = f;
|
cgf->function = f;
|
||||||
functions_.insert(std::pair<uint32_t, CodegenFunction*>(
|
functions_.insert(std::pair<uint32_t, CodegenFunction*>(
|
||||||
fn->start_address, cgf));
|
fn->start_address, cgf));
|
||||||
|
|
Loading…
Reference in New Issue