Skip to content

Commit 7f47b0c

Browse files
committedApr 11, 2017
run alwaysinline pass in debug mode
before this commit, the optimized IR code that is displayed in --verbose mode is not actually what gets emitted to an object file. that is now corrected, and we make sure to run the alwaysinliner pass even in debug mode, so you can rely on "inline" keyword inlining a function, guaranteed. See #306
1 parent 11a6550 commit 7f47b0c

File tree

4 files changed

+85
-49
lines changed

4 files changed

+85
-49
lines changed
 

‎src/codegen.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3826,8 +3826,8 @@ static void do_code_gen(CodeGen *g) {
38263826
Buf *out_file_o = buf_create_from_buf(g->root_out_name);
38273827
const char *o_ext = target_o_file_ext(&g->zig_target);
38283828
buf_append_str(out_file_o, o_ext);
3829-
if (LLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(out_file_o),
3830-
LLVMObjectFile, &err_msg))
3829+
if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(out_file_o),
3830+
LLVMObjectFile, &err_msg, !g->is_release_build))
38313831
{
38323832
zig_panic("unable to write object file: %s", err_msg);
38333833
}

‎src/link.cpp

+4-12
Original file line numberDiff line numberDiff line change
@@ -746,18 +746,10 @@ void codegen_link(CodeGen *g, const char *out_file) {
746746
buf_resize(&lj.out_file, 0);
747747
}
748748

749-
bool is_optimized = g->is_release_build;
750-
if (is_optimized) {
751-
if (g->verbose) {
752-
fprintf(stderr, "\nOptimization:\n");
753-
fprintf(stderr, "---------------\n");
754-
}
755-
756-
ZigLLVMOptimizeModule(g->target_machine, g->module);
757-
758-
if (g->verbose) {
759-
LLVMDumpModule(g->module);
760-
}
749+
if (g->verbose) {
750+
fprintf(stderr, "\nOptimization:\n");
751+
fprintf(stderr, "---------------\n");
752+
LLVMDumpModule(g->module);
761753
}
762754
if (g->verbose) {
763755
fprintf(stderr, "\nLink:\n");

‎src/zig_llvm.cpp

+77-34
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <llvm/Target/TargetMachine.h>
4242
#include <llvm/Transforms/IPO.h>
4343
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
44+
#include <llvm/Transforms/IPO/AlwaysInliner.h>
4445
#include <llvm/Transforms/Scalar.h>
4546

4647
#include <lld/Driver/Driver.h>
@@ -72,66 +73,108 @@ char *ZigLLVMGetNativeFeatures(void) {
7273
return strdup(features.getString().c_str());
7374
}
7475

75-
static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
76+
static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
7677
PM.add(createAddDiscriminatorsPass());
7778
}
7879

80+
#ifndef NDEBUG
81+
static const bool assertions_on = true;
82+
#else
83+
static const bool assertions_on = false;
84+
#endif
7985

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+
}
8195
TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
96+
target_machine->setO0WantsFastISel(true);
97+
8298
Module* module = unwrap(module_ref);
83-
TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple()));
8499

85100
PassManagerBuilder *PMBuilder = new PassManagerBuilder();
86101
PMBuilder->OptLevel = target_machine->getOptLevel();
87102
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;
97103

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;
99120

121+
TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple()));
100122
PMBuilder->LibraryInfo = &tlii;
101123

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+
}
103135

104136
// 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());
114142
}
115-
PMBuilder->populateFunctionPassManager(*FPM);
143+
PMBuilder->populateFunctionPassManager(FPM);
116144

117145
// 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+
}
123163

124164
// run per function optimization passes
125-
FPM->doInitialization();
165+
FPM.doInitialization();
126166
for (Function &F : *module)
127167
if (!F.isDeclaration())
128-
FPM->run(F);
129-
FPM->doFinalization();
168+
FPM.run(F);
169+
FPM.doFinalization();
130170

131-
// run per module optimization passes
132-
MPM->run(*module);
171+
MPM.run(*module);
172+
173+
dest.flush();
174+
return false;
133175
}
134176

177+
135178
LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
136179
unsigned NumArgs, unsigned CC, const char *Name)
137180
{

‎src/zig_llvm.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
3434
char *ZigLLVMGetHostCPUName(void);
3535
char *ZigLLVMGetNativeFeatures(void);
3636

37-
void ZigLLVMOptimizeModule(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref);
37+
bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
38+
const char *filename, LLVMCodeGenFileType file_type, char **error_message, bool is_debug);
3839

3940
LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
4041
unsigned NumArgs, unsigned CC, const char *Name);

0 commit comments

Comments
 (0)
Please sign in to comment.