|
41 | 41 | #include <llvm/Target/TargetMachine.h>
|
42 | 42 | #include <llvm/Transforms/IPO.h>
|
43 | 43 | #include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
| 44 | +#include <llvm/Transforms/IPO/AlwaysInliner.h> |
44 | 45 | #include <llvm/Transforms/Scalar.h>
|
45 | 46 |
|
46 | 47 | #include <lld/Driver/Driver.h>
|
@@ -72,66 +73,108 @@ char *ZigLLVMGetNativeFeatures(void) {
|
72 | 73 | return strdup(features.getString().c_str());
|
73 | 74 | }
|
74 | 75 |
|
75 |
| -static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { |
| 76 | +static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { |
76 | 77 | PM.add(createAddDiscriminatorsPass());
|
77 | 78 | }
|
78 | 79 |
|
| 80 | +#ifndef NDEBUG |
| 81 | +static const bool assertions_on = true; |
| 82 | +#else |
| 83 | +static const bool assertions_on = false; |
| 84 | +#endif |
79 | 85 |
|
80 |
| -void ZigLLVMOptimizeModule(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref) { |
| 86 | +bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 87 | + const char *filename, LLVMCodeGenFileType file_type, char **error_message, bool is_debug) |
| 88 | +{ |
| 89 | + std::error_code EC; |
| 90 | + raw_fd_ostream dest(filename, EC, sys::fs::F_None); |
| 91 | + if (EC) { |
| 92 | + *error_message = strdup(EC.message().c_str()); |
| 93 | + return true; |
| 94 | + } |
81 | 95 | TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
|
| 96 | + target_machine->setO0WantsFastISel(true); |
| 97 | + |
82 | 98 | Module* module = unwrap(module_ref);
|
83 |
| - TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); |
84 | 99 |
|
85 | 100 | PassManagerBuilder *PMBuilder = new PassManagerBuilder();
|
86 | 101 | PMBuilder->OptLevel = target_machine->getOptLevel();
|
87 | 102 | PMBuilder->SizeLevel = 0;
|
88 |
| - PMBuilder->BBVectorize = true; |
89 |
| - PMBuilder->SLPVectorize = true; |
90 |
| - PMBuilder->LoopVectorize = true; |
91 |
| - |
92 |
| - PMBuilder->DisableUnitAtATime = false; |
93 |
| - PMBuilder->DisableUnrollLoops = false; |
94 |
| - PMBuilder->MergeFunctions = true; |
95 |
| - PMBuilder->PrepareForLTO = true; |
96 |
| - PMBuilder->RerollLoops = true; |
97 | 103 |
|
98 |
| - PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); |
| 104 | + PMBuilder->DisableTailCalls = is_debug; |
| 105 | + PMBuilder->DisableUnitAtATime = is_debug; |
| 106 | + PMBuilder->DisableUnrollLoops = is_debug; |
| 107 | + PMBuilder->BBVectorize = !is_debug; |
| 108 | + PMBuilder->SLPVectorize = !is_debug; |
| 109 | + PMBuilder->LoopVectorize = !is_debug; |
| 110 | + PMBuilder->RerollLoops = !is_debug; |
| 111 | + PMBuilder->LoadCombine = !is_debug; |
| 112 | + PMBuilder->NewGVN = !is_debug; |
| 113 | + PMBuilder->DisableGVNLoadPRE = is_debug; |
| 114 | + PMBuilder->VerifyInput = assertions_on; |
| 115 | + PMBuilder->VerifyOutput = assertions_on; |
| 116 | + PMBuilder->MergeFunctions = !is_debug; |
| 117 | + PMBuilder->PrepareForLTO = false; |
| 118 | + PMBuilder->PrepareForThinLTO = false; |
| 119 | + PMBuilder->PerformThinLTO = false; |
99 | 120 |
|
| 121 | + TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); |
100 | 122 | PMBuilder->LibraryInfo = &tlii;
|
101 | 123 |
|
102 |
| - PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel); |
| 124 | + if (is_debug) { |
| 125 | + PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false); |
| 126 | + } else { |
| 127 | + PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, |
| 128 | + [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { |
| 129 | + target_machine->addEarlyAsPossiblePasses(PM); |
| 130 | + }); |
| 131 | + |
| 132 | + PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass); |
| 133 | + PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel); |
| 134 | + } |
103 | 135 |
|
104 | 136 | // Set up the per-function pass manager.
|
105 |
| - legacy::FunctionPassManager *FPM = new legacy::FunctionPassManager(module); |
106 |
| - FPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); |
107 |
| -#ifndef NDEBUG |
108 |
| - bool verify_module = true; |
109 |
| -#else |
110 |
| - bool verify_module = false; |
111 |
| -#endif |
112 |
| - if (verify_module) { |
113 |
| - FPM->add(createVerifierPass()); |
| 137 | + legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module); |
| 138 | + FPM.add(new TargetLibraryInfoWrapperPass(tlii)); |
| 139 | + FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); |
| 140 | + if (assertions_on) { |
| 141 | + FPM.add(createVerifierPass()); |
114 | 142 | }
|
115 |
| - PMBuilder->populateFunctionPassManager(*FPM); |
| 143 | + PMBuilder->populateFunctionPassManager(FPM); |
116 | 144 |
|
117 | 145 | // Set up the per-module pass manager.
|
118 |
| - legacy::PassManager *MPM = new legacy::PassManager(); |
119 |
| - MPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); |
120 |
| - |
121 |
| - PMBuilder->populateModulePassManager(*MPM); |
122 |
| - |
| 146 | + legacy::PassManager MPM; |
| 147 | + MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); |
| 148 | + PMBuilder->populateModulePassManager(MPM); |
| 149 | + |
| 150 | + TargetMachine::CodeGenFileType ft; |
| 151 | + switch (file_type) { |
| 152 | + case LLVMAssemblyFile: |
| 153 | + ft = TargetMachine::CGFT_AssemblyFile; |
| 154 | + break; |
| 155 | + default: |
| 156 | + ft = TargetMachine::CGFT_ObjectFile; |
| 157 | + break; |
| 158 | + } |
| 159 | + if (target_machine->addPassesToEmitFile(MPM, dest, ft)) { |
| 160 | + *error_message = strdup("TargetMachine can't emit a file of this type"); |
| 161 | + return true; |
| 162 | + } |
123 | 163 |
|
124 | 164 | // run per function optimization passes
|
125 |
| - FPM->doInitialization(); |
| 165 | + FPM.doInitialization(); |
126 | 166 | for (Function &F : *module)
|
127 | 167 | if (!F.isDeclaration())
|
128 |
| - FPM->run(F); |
129 |
| - FPM->doFinalization(); |
| 168 | + FPM.run(F); |
| 169 | + FPM.doFinalization(); |
130 | 170 |
|
131 |
| - // run per module optimization passes |
132 |
| - MPM->run(*module); |
| 171 | + MPM.run(*module); |
| 172 | + |
| 173 | + dest.flush(); |
| 174 | + return false; |
133 | 175 | }
|
134 | 176 |
|
| 177 | + |
135 | 178 | LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
|
136 | 179 | unsigned NumArgs, unsigned CC, const char *Name)
|
137 | 180 | {
|
|
0 commit comments