From 385a4ee23b6d075780a33a304f3120f44d8519a8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 23 Jan 2013 22:38:59 -0800 Subject: [PATCH] Cleaning up function creation. --- include/xenia/cpu/codegen/module_generator.h | 1 + src/cpu/codegen/function_generator.cc | 4 +- src/cpu/codegen/module_generator.cc | 72 +++++++++----------- 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/include/xenia/cpu/codegen/module_generator.h b/include/xenia/cpu/codegen/module_generator.h index 62ee94028..62965cd27 100644 --- a/include/xenia/cpu/codegen/module_generator.h +++ b/include/xenia/cpu/codegen/module_generator.h @@ -52,6 +52,7 @@ private: CodegenFunction* GetCodegenFunction(uint32_t address); void AddImports(); + llvm::Function* CreateFunctionDefinition(const char* name); void AddMissingImport(sdb::FunctionSymbol* fn); void AddPresentImport(sdb::FunctionSymbol* fn); void PrepareFunction(sdb::FunctionSymbol* fn); diff --git a/src/cpu/codegen/function_generator.cc b/src/cpu/codegen/function_generator.cc index 7ed409b08..7f11e370e 100644 --- a/src/cpu/codegen/function_generator.cc +++ b/src/cpu/codegen/function_generator.cc @@ -203,7 +203,7 @@ Value* FunctionGenerator::LoadStateValue(uint32_t offset, Type* type, PointerType* pointerTy = PointerType::getUnqual(type); Function::arg_iterator args = gen_fn_->arg_begin(); Value* statePtr = args; - Value* address = builder_->CreateConstInBoundsGEP1_32( + Value* address = builder_->CreateConstInBoundsGEP1_64( statePtr, offset); Value* ptr = builder_->CreatePointerCast(address, pointerTy); return builder_->CreateLoad(ptr, name); @@ -214,7 +214,7 @@ void FunctionGenerator::StoreStateValue(uint32_t offset, Type* type, PointerType* pointerTy = PointerType::getUnqual(type); Function::arg_iterator args = gen_fn_->arg_begin(); Value* statePtr = args; - Value* address = builder_->CreateConstInBoundsGEP1_32( + Value* address = builder_->CreateConstInBoundsGEP1_64( statePtr, offset); Value* ptr = builder_->CreatePointerCast(address, pointerTy); diff --git a/src/cpu/codegen/module_generator.cc b/src/cpu/codegen/module_generator.cc index 4147dce8d..3e25c5d18 100644 --- a/src/cpu/codegen/module_generator.cc +++ b/src/cpu/codegen/module_generator.cc @@ -132,37 +132,52 @@ ModuleGenerator::CodegenFunction* ModuleGenerator::GetCodegenFunction( return NULL; } -void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) { +Function* ModuleGenerator::CreateFunctionDefinition(const char* name) { Module* m = gen_module_; 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 args; 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, ArrayRef(args), false); Function* f = cast(m->getOrInsertFunction( - StringRef(fn->name), ft, attrs)); - f->setCallingConv(CallingConv::C); + StringRef(name), ft)); 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(); + // 'state' Value* fn_arg = fn_args++; 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. BasicBlock* block = BasicBlock::Create(context, "entry", f); IRBuilder<> builder(block); - Value* tmp = builder.getInt32(0); - builder.CreateRet(tmp); + builder.CreateRetVoid(); OptimizeFunction(m, f); @@ -184,35 +199,16 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) { } void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) { - Module* m = gen_module_; - LLVMContext& context = m->getContext(); + // Module* m = gen_module_; + // 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 args; - args.push_back(PointerType::getUnqual(Type::getInt8Ty(context))); - Type* return_type = Type::getVoidTy(context); - - FunctionType* ft = FunctionType::get(return_type, - ArrayRef(args), false); - XEASSERTNOTNULL(fn->name); - Function* f = cast( - 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"); + // Create the function (and setup args/attributes/etc). + Function* f = CreateFunctionDefinition(fn->name); + // Setup our codegen wrapper to keep all the pointers together. CodegenFunction* cgf = new CodegenFunction(); cgf->symbol = fn; - cgf->function_type = ft; + cgf->function_type = f->getFunctionType(); cgf->function = f; functions_.insert(std::pair( fn->start_address, cgf));