aboutsummaryrefslogtreecommitdiff
path: root/src/zig_llvm.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2015-11-27 15:46:06 -0700
committerAndrew Kelley <superjoe30@gmail.com>2015-11-27 15:46:06 -0700
commit024052b4483b13639e998ef34dc097a24860c612 (patch)
tree267af11f1d492a1c532a671079ade5520564299a /src/zig_llvm.cpp
parent9ca9a2c5540683a54bae597c59152d06d095beef (diff)
downloadzig-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.cpp134
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));
+}