Skip to content

Commit fea6232

Browse files
committed
rustc: Add a Link module; move crate writing to it to slim down trans slightly
1 parent 7296482 commit fea6232

File tree

5 files changed

+197
-173
lines changed

5 files changed

+197
-173
lines changed

Diff for: src/comp/back/Link.rs

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import driver.session;
2+
import lib.llvm.llvm;
3+
import middle.trans;
4+
import std._str;
5+
6+
import lib.llvm.llvm.ModuleRef;
7+
import lib.llvm.llvm.ValueRef;
8+
import lib.llvm.mk_pass_manager;
9+
import lib.llvm.mk_target_data;
10+
import lib.llvm.mk_type_names;
11+
12+
tag output_type {
13+
output_type_none;
14+
output_type_bitcode;
15+
output_type_assembly;
16+
output_type_object;
17+
}
18+
19+
mod Write {
20+
fn is_object_or_assembly(output_type ot) -> bool {
21+
if (ot == output_type_assembly) {
22+
ret true;
23+
}
24+
if (ot == output_type_object) {
25+
ret true;
26+
}
27+
ret false;
28+
}
29+
30+
// Decides what to call an intermediate file, given the name of the output
31+
// and the extension to use.
32+
fn mk_intermediate_name(str output_path, str extension) -> str {
33+
auto dot_pos = _str.index(output_path, '.' as u8);
34+
auto stem;
35+
if (dot_pos < 0) {
36+
stem = output_path;
37+
} else {
38+
stem = _str.substr(output_path, 0u, dot_pos as uint);
39+
}
40+
ret stem + "." + extension;
41+
}
42+
43+
fn run_passes(session.session sess, ModuleRef llmod, str output) {
44+
auto pm = mk_pass_manager();
45+
auto opts = sess.get_opts();
46+
47+
// TODO: run the linter here also, once there are llvm-c bindings for
48+
// it.
49+
50+
// Generate a pre-optimization intermediate file if -save-temps was
51+
// specified.
52+
if (opts.save_temps) {
53+
alt (opts.output_type) {
54+
case (output_type_bitcode) {
55+
if (opts.optimize) {
56+
auto filename = mk_intermediate_name(output,
57+
"no-opt.bc");
58+
llvm.LLVMWriteBitcodeToFile(llmod,
59+
_str.buf(filename));
60+
}
61+
}
62+
case (_) {
63+
auto filename = mk_intermediate_name(output, "bc");
64+
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename));
65+
}
66+
}
67+
}
68+
69+
// FIXME: This is mostly a copy of the bits of opt's -O2 that are
70+
// available in the C api.
71+
// FIXME2: We might want to add optimization levels like -O1, -O2,
72+
// -Os, etc
73+
// FIXME3: Should we expose and use the pass lists used by the opt
74+
// tool?
75+
if (opts.optimize) {
76+
auto fpm = mk_pass_manager();
77+
78+
// createStandardFunctionPasses
79+
llvm.LLVMAddTypeBasedAliasAnalysisPass(fpm.llpm);
80+
llvm.LLVMAddBasicAliasAnalysisPass(fpm.llpm);
81+
llvm.LLVMAddCFGSimplificationPass(fpm.llpm);
82+
llvm.LLVMAddScalarReplAggregatesPass(fpm.llpm);
83+
llvm.LLVMAddEarlyCSEPass(fpm.llpm);
84+
85+
llvm.LLVMRunPassManager(fpm.llpm, llmod);
86+
87+
// createStandardModulePasses
88+
llvm.LLVMAddTypeBasedAliasAnalysisPass(pm.llpm);
89+
llvm.LLVMAddBasicAliasAnalysisPass(pm.llpm);
90+
llvm.LLVMAddGlobalOptimizerPass(pm.llpm);
91+
llvm.LLVMAddIPSCCPPass(pm.llpm);
92+
llvm.LLVMAddDeadArgEliminationPass(pm.llpm);
93+
llvm.LLVMAddInstructionCombiningPass(pm.llpm);
94+
llvm.LLVMAddCFGSimplificationPass(pm.llpm);
95+
llvm.LLVMAddPruneEHPass(pm.llpm);
96+
llvm.LLVMAddFunctionInliningPass(pm.llpm);
97+
llvm.LLVMAddFunctionAttrsPass(pm.llpm);
98+
llvm.LLVMAddScalarReplAggregatesPassSSA(pm.llpm);
99+
llvm.LLVMAddEarlyCSEPass(pm.llpm);
100+
llvm.LLVMAddSimplifyLibCallsPass(pm.llpm);
101+
llvm.LLVMAddJumpThreadingPass(pm.llpm);
102+
llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm);
103+
llvm.LLVMAddCFGSimplificationPass(pm.llpm);
104+
llvm.LLVMAddInstructionCombiningPass(pm.llpm);
105+
llvm.LLVMAddTailCallEliminationPass(pm.llpm);
106+
llvm.LLVMAddCFGSimplificationPass(pm.llpm);
107+
llvm.LLVMAddReassociatePass(pm.llpm);
108+
llvm.LLVMAddLoopRotatePass(pm.llpm);
109+
llvm.LLVMAddLICMPass(pm.llpm);
110+
llvm.LLVMAddLoopUnswitchPass(pm.llpm);
111+
llvm.LLVMAddInstructionCombiningPass(pm.llpm);
112+
llvm.LLVMAddIndVarSimplifyPass(pm.llpm);
113+
llvm.LLVMAddLoopIdiomPass(pm.llpm);
114+
llvm.LLVMAddLoopDeletionPass(pm.llpm);
115+
llvm.LLVMAddLoopUnrollPass(pm.llpm);
116+
llvm.LLVMAddInstructionCombiningPass(pm.llpm);
117+
llvm.LLVMAddGVNPass(pm.llpm);
118+
llvm.LLVMAddMemCpyOptPass(pm.llpm);
119+
llvm.LLVMAddSCCPPass(pm.llpm);
120+
llvm.LLVMAddInstructionCombiningPass(pm.llpm);
121+
llvm.LLVMAddJumpThreadingPass(pm.llpm);
122+
llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm);
123+
llvm.LLVMAddDeadStoreEliminationPass(pm.llpm);
124+
llvm.LLVMAddAggressiveDCEPass(pm.llpm);
125+
llvm.LLVMAddCFGSimplificationPass(pm.llpm);
126+
llvm.LLVMAddStripDeadPrototypesPass(pm.llpm);
127+
llvm.LLVMAddDeadTypeEliminationPass(pm.llpm);
128+
llvm.LLVMAddConstantMergePass(pm.llpm);
129+
}
130+
131+
if (opts.verify) {
132+
llvm.LLVMAddVerifierPass(pm.llpm);
133+
}
134+
135+
// TODO: Write .s if -c was specified and -save-temps was on.
136+
if (is_object_or_assembly(opts.output_type)) {
137+
let int LLVMAssemblyFile = 0;
138+
let int LLVMObjectFile = 1;
139+
let int LLVMNullFile = 2;
140+
auto FileType;
141+
if (opts.output_type == output_type_object) {
142+
FileType = LLVMObjectFile;
143+
} else {
144+
FileType = LLVMAssemblyFile;
145+
}
146+
147+
// Write optimized bitcode if --save-temps was on.
148+
if (opts.save_temps) {
149+
alt (opts.output_type) {
150+
case (output_type_bitcode) { /* nothing to do */ }
151+
case (_) {
152+
auto filename = mk_intermediate_name(output,
153+
"opt.bc");
154+
llvm.LLVMRunPassManager(pm.llpm, llmod);
155+
llvm.LLVMWriteBitcodeToFile(llmod,
156+
_str.buf(filename));
157+
pm = mk_pass_manager();
158+
}
159+
}
160+
}
161+
162+
llvm.LLVMRustWriteOutputFile(pm.llpm, llmod,
163+
_str.buf(x86.get_target_triple()),
164+
_str.buf(output),
165+
FileType);
166+
llvm.LLVMDisposeModule(llmod);
167+
ret;
168+
}
169+
170+
llvm.LLVMRunPassManager(pm.llpm, llmod);
171+
172+
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
173+
llvm.LLVMDisposeModule(llmod);
174+
}
175+
}
176+

Diff for: src/comp/driver/rustc.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import middle.capture;
1111
import middle.ty;
1212
import middle.typeck;
1313
import middle.typestate_check;
14+
import back.Link;
1415
import lib.llvm;
1516
import util.common;
1617

@@ -30,6 +31,8 @@ import std.GetOpts.optmulti;
3031
import std.GetOpts.optflag;
3132
import std.GetOpts.opt_present;
3233

34+
import back.Link.output_type;
35+
3336
fn default_environment(session.session sess,
3437
str argv0,
3538
str input) -> eval.env {
@@ -86,7 +89,7 @@ fn compile_input(session.session sess,
8689
auto p = parser.new_parser(sess, env, def, input, 0u);
8790
auto crate = time[@ast.crate](time_passes, "parsing",
8891
bind parse_input(sess, p, input));
89-
if (sess.get_opts().output_type == trans.output_type_none) {ret;}
92+
if (sess.get_opts().output_type == Link.output_type_none) {ret;}
9093

9194
crate = time[@ast.crate](time_passes, "external crate reading",
9295
bind creader.read_crates(sess, crate));
@@ -111,7 +114,7 @@ fn compile_input(session.session sess,
111114
bind trans.trans_crate(sess, crate, ty_cx, type_cache, output));
112115

113116
time[()](time_passes, "LLVM passes",
114-
bind trans.run_passes(sess, llmod, output));
117+
bind Link.Write.run_passes(sess, llmod, output));
115118
}
116119

117120
fn pretty_print_input(session.session sess,
@@ -197,14 +200,16 @@ fn main(vec[str] args) {
197200
auto shared = opt_present(match, "shared");
198201
auto output_file = GetOpts.opt_maybe_str(match, "o");
199202
auto library_search_paths = GetOpts.opt_strs(match, "L");
200-
auto output_type = trans.output_type_bitcode;
203+
204+
auto output_type = Link.output_type_bitcode;
201205
if (opt_present(match, "parse-only")) {
202-
output_type = trans.output_type_none;
206+
output_type = Link.output_type_none;
203207
} else if (opt_present(match, "S")) {
204-
output_type = trans.output_type_assembly;
208+
output_type = Link.output_type_assembly;
205209
} else if (opt_present(match, "c")) {
206-
output_type = trans.output_type_object;
210+
output_type = Link.output_type_object;
207211
}
212+
208213
auto verify = !opt_present(match, "noverify");
209214
auto save_temps = opt_present(match, "save-temps");
210215
// FIXME: Maybe we should support -O0, -O1, -Os, etc
@@ -268,14 +273,10 @@ fn main(vec[str] args) {
268273
let vec[str] parts = _str.split(ifile, '.' as u8);
269274
_vec.pop[str](parts);
270275
alt (output_type) {
271-
case (trans.output_type_none)
272-
{ parts += vec("pp"); }
273-
case (trans.output_type_bitcode)
274-
{ parts += vec("bc"); }
275-
case (trans.output_type_assembly)
276-
{ parts += vec("s"); }
277-
case (trans.output_type_object)
278-
{ parts += vec("o"); }
276+
case (Link.output_type_none) { parts += vec("pp"); }
277+
case (Link.output_type_bitcode) { parts += vec("bc"); }
278+
case (Link.output_type_assembly) { parts += vec("s"); }
279+
case (Link.output_type_object) { parts += vec("o"); }
279280
}
280281
auto ofile = _str.connect(parts, ".");
281282
compile_input(sess, env, ifile, ofile);

Diff for: src/comp/driver/session.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type options = rec(bool shared,
3232
bool run_typestate,
3333
bool save_temps,
3434
bool time_passes,
35-
middle.trans.output_type output_type,
35+
back.Link.output_type output_type,
3636
vec[str] library_search_paths,
3737
str sysroot);
3838

0 commit comments

Comments
 (0)