diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-11-27 15:46:06 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-11-27 15:46:06 -0700 |
| commit | 024052b4483b13639e998ef34dc097a24860c612 (patch) | |
| tree | 267af11f1d492a1c532a671079ade5520564299a /src/zig_llvm.cpp | |
| parent | 9ca9a2c5540683a54bae597c59152d06d095beef (diff) | |
| download | zig-024052b4483b13639e998ef34dc097a24860c612.tar.gz zig-024052b4483b13639e998ef34dc097a24860c612.zip | |
add pub and export visibility modifiers and optimization
Diffstat (limited to 'src/zig_llvm.cpp')
| -rw-r--r-- | src/zig_llvm.cpp | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index a43e0a541b..89d0563b97 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -10,7 +10,19 @@ #include <llvm/InitializePasses.h> #include <llvm/PassRegistry.h> #include <llvm/MC/SubtargetFeature.h> - +#include <llvm/Support/raw_ostream.h> +#include <llvm/Support/FileSystem.h> +#include <llvm/Target/TargetMachine.h> +#include <llvm/IR/LegacyPassManager.h> +#include <llvm/IR/Module.h> +#include <llvm/IR/Verifier.h> +#include <llvm/IR/Instructions.h> +#include <llvm/IR/IRBuilder.h> +#include <llvm/Analysis/TargetLibraryInfo.h> +#include <llvm/Analysis/TargetTransformInfo.h> +#include <llvm/Transforms/IPO.h> +#include <llvm/Transforms/IPO/PassManagerBuilder.h> +#include <llvm/Transforms/Scalar.h> using namespace llvm; @@ -42,3 +54,123 @@ char *LLVMZigGetNativeFeatures(void) { return strdup(features.getString().c_str()); } + +static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { + PM.add(createAddDiscriminatorsPass()); +} + + +void LLVMZigOptimizeModule(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref) { + TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); + Module* module = unwrap(module_ref); + TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); + + PassManagerBuilder *PMBuilder = new PassManagerBuilder(); + PMBuilder->OptLevel = target_machine->getOptLevel(); + PMBuilder->SizeLevel = 0; + PMBuilder->BBVectorize = true; + PMBuilder->SLPVectorize = true; + PMBuilder->LoopVectorize = true; + + PMBuilder->DisableUnitAtATime = false; + PMBuilder->DisableUnrollLoops = false; + PMBuilder->MergeFunctions = true; + PMBuilder->PrepareForLTO = true; + PMBuilder->RerollLoops = true; + + PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); + + PMBuilder->LibraryInfo = &tlii; + + PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel); + + // Set up the per-function pass manager. + legacy::FunctionPassManager *FPM = new legacy::FunctionPassManager(module); + FPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); +#ifndef NDEBUG + bool verify_module = true; +#else + bool verify_module = false; +#endif + if (verify_module) { + FPM->add(createVerifierPass()); + } + PMBuilder->populateFunctionPassManager(*FPM); + + // Set up the per-module pass manager. + legacy::PassManager *MPM = new legacy::PassManager(); + MPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); + + PMBuilder->populateModulePassManager(*MPM); + + + // run per function optimization passes + FPM->doInitialization(); + for (Function &F : *module) + if (!F.isDeclaration()) + FPM->run(F); + FPM->doFinalization(); + + // run per module optimization passes + MPM->run(*module); +} + +static LLVMBool LLVMZigTargetMachineEmit(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, + raw_pwrite_stream &out_stream, LLVMCodeGenFileType codegen, char **err_msg) +{ + TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); + Module* module = unwrap(module_ref); + TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); + + legacy::PassManager pass; + + pass.add(new TargetLibraryInfoWrapperPass(tlii)); + + const DataLayout *td = target_machine->getDataLayout(); + + if (!td) { + *err_msg = strdup("No DataLayout in TargetMachine"); + return true; + } + module->setDataLayout(*td); + + + TargetMachine::CodeGenFileType ft; + switch (codegen) { + case LLVMAssemblyFile: + ft = TargetMachine::CGFT_AssemblyFile; + break; + default: + ft = TargetMachine::CGFT_ObjectFile; + break; + } + if (target_machine->addPassesToEmitFile(pass, out_stream, ft)) { + *err_msg = strdup("TargetMachine can't emit a file of this type"); + return true; + } + + pass.run(*module); + + out_stream.flush(); + return false; +} + +LLVMBool LLVMZigTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, + char* filename, LLVMCodeGenFileType codegen, char** err_msg) +{ + std::error_code error_code; + raw_fd_ostream dest(filename, error_code, sys::fs::F_None); + if (error_code) { + *err_msg = strdup(error_code.message().c_str()); + return true; + } + return LLVMZigTargetMachineEmit(targ_machine_ref, module_ref, dest, codegen, err_msg); +} + +LLVMValueRef LLVMZigBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, + unsigned NumArgs, unsigned CC, const char *Name) +{ + CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name); + call_inst->setCallingConv(CC); + return wrap(unwrap(B)->Insert(call_inst)); +} |
