Skip to content

Commit 2214b68

Browse files
committed
Add a -S option for producing assembly. I will move more of it to
rust once the necessary APIs are available in C.
1 parent 790084c commit 2214b68

File tree

5 files changed

+68
-20
lines changed

5 files changed

+68
-20
lines changed

src/comp/driver/rustc.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ impure fn compile_input(session.session sess,
6060
str input, str output,
6161
bool shared,
6262
bool optimize,
63-
bool parse_only,
63+
trans.output_type ot,
6464
vec[str] library_search_paths) {
6565
auto def = tup(0, 0);
6666
auto p = parser.new_parser(sess, env, def, input, 0u);
6767
auto crate = parse_input(sess, p, input);
68-
if (parse_only) {ret;}
68+
if (ot == trans.output_type_none) {ret;}
6969
crate = creader.read_crates(sess, crate, library_search_paths);
7070
crate = resolve.resolve_crate(sess, crate);
7171
capture.check_for_captures(sess, crate);
@@ -74,7 +74,8 @@ impure fn compile_input(session.session sess,
7474
auto type_cache = typeck_result._1;
7575
// FIXME: uncomment once typestate_check works
7676
// crate = typestate_check.check_crate(crate);
77-
trans.trans_crate(sess, crate, type_cache, output, shared, optimize);
77+
trans.trans_crate(sess, crate, type_cache, output, shared, optimize,
78+
ot);
7879
}
7980

8081
impure fn pretty_print_input(session.session sess,
@@ -137,7 +138,7 @@ impure fn main(vec[str] args) {
137138
let bool shared = false;
138139
let bool pretty = false;
139140
let bool ls = false;
140-
let bool parse_only = false;
141+
auto ot = trans.output_type_bitcode;
141142
let bool glue = false;
142143

143144
// FIXME: Maybe we should support -O0, -O1, -Os, etc
@@ -163,7 +164,9 @@ impure fn main(vec[str] args) {
163164
} else if (_str.eq(arg, "-ls")) {
164165
ls = true;
165166
} else if (_str.eq(arg, "-parse-only")) {
166-
parse_only = true;
167+
ot = trans.output_type_none;
168+
} else if (_str.eq(arg, "-S")) {
169+
ot = trans.output_type_assembly;
167170
} else if (_str.eq(arg, "-o")) {
168171
if (i+1u < len) {
169172
output_file = some(args.(i+1u));
@@ -207,10 +210,10 @@ impure fn main(vec[str] args) {
207210
if (glue) {
208211
alt (output_file) {
209212
case (none[str]) {
210-
middle.trans.make_common_glue("glue.bc", optimize);
213+
middle.trans.make_common_glue("glue.bc", optimize, ot);
211214
}
212215
case (some[str](?s)) {
213-
middle.trans.make_common_glue(s, optimize);
216+
middle.trans.make_common_glue(s, optimize, ot);
214217
}
215218
}
216219
ret;
@@ -236,12 +239,12 @@ impure fn main(vec[str] args) {
236239
parts += vec(".bc");
237240
auto ofile = _str.concat(parts);
238241
compile_input(sess, env, ifile, ofile, shared,
239-
optimize, parse_only,
242+
optimize, ot,
240243
library_search_paths);
241244
}
242245
case (some[str](?ofile)) {
243246
compile_input(sess, env, ifile, ofile, shared,
244-
optimize, parse_only,
247+
optimize, ot,
245248
library_search_paths);
246249
}
247250
}

src/comp/lib/llvm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,9 @@ native mod llvm = llvm_lib {
815815
fn LLVMRustCreateMemoryBufferWithContentsOfFile(sbuf Path) ->
816816
MemoryBufferRef;
817817

818+
fn LLVMRustWriteAssembly(PassManagerRef PM, ModuleRef M,
819+
sbuf Triple, sbuf Output);
820+
818821
/** Returns a string describing the last error caused by an LLVMRust*
819822
call. */
820823
fn LLVMRustGetLastError() -> sbuf;

src/comp/middle/trans.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6675,8 +6675,14 @@ fn trap(@block_ctxt bcx) {
66756675
let vec[ValueRef] v = vec();
66766676
bcx.build.Call(bcx.fcx.ccx.intrinsics.get("llvm.trap"), v);
66776677
}
6678+
tag output_type {
6679+
output_type_none;
6680+
output_type_bitcode;
6681+
output_type_assembly;
6682+
}
66786683

6679-
fn run_passes(ModuleRef llmod, bool opt) {
6684+
fn run_passes(ModuleRef llmod, bool opt, str output,
6685+
output_type ot) {
66806686
auto pm = mk_pass_manager();
66816687

66826688
// TODO: run the linter here also, once there are llvm-c bindings for it.
@@ -6741,7 +6747,18 @@ fn run_passes(ModuleRef llmod, bool opt) {
67416747
llvm.LLVMAddConstantMergePass(pm.llpm);
67426748
}
67436749
llvm.LLVMAddVerifierPass(pm.llpm);
6750+
6751+
if (ot == output_type_assembly) {
6752+
llvm.LLVMRustWriteAssembly(pm.llpm, llmod,
6753+
_str.buf(x86.get_target_triple()),
6754+
_str.buf(output));
6755+
ret;
6756+
}
6757+
67446758
llvm.LLVMRunPassManager(pm.llpm, llmod);
6759+
6760+
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
6761+
llvm.LLVMDisposeModule(llmod);
67456762
}
67466763

67476764
fn decl_no_op_type_glue(ModuleRef llmod, type_names tn) -> ValueRef {
@@ -7073,7 +7090,8 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
70737090
vec_append_glue = make_vec_append_glue(llmod, tn));
70747091
}
70757092

7076-
fn make_common_glue(str output, bool optimize) {
7093+
fn make_common_glue(str output, bool optimize,
7094+
output_type ot) {
70777095
// FIXME: part of this is repetitive and is probably a good idea
70787096
// to autogen it, but things like the memcpy implementation are not
70797097
// and it might be better to just check in a .ll file.
@@ -7099,15 +7117,12 @@ fn make_common_glue(str output, bool optimize) {
70997117

71007118
trans_exit_task_glue(glues, new_str_hash[ValueRef](), tn, llmod);
71017119

7102-
run_passes(llmod, optimize);
7103-
7104-
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
7105-
llvm.LLVMDisposeModule(llmod);
7120+
run_passes(llmod, optimize, output, ot);
71067121
}
71077122

71087123
fn trans_crate(session.session sess, @ast.crate crate,
71097124
&ty.type_cache type_cache, str output, bool shared,
7110-
bool optimize) {
7125+
bool optimize, output_type ot) {
71117126
auto llmod =
71127127
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
71137128
llvm.LLVMGetGlobalContext());
@@ -7170,10 +7185,7 @@ fn trans_crate(session.session sess, @ast.crate crate,
71707185
// Translate the metadata.
71717186
middle.metadata.write_metadata(cx, crate);
71727187

7173-
run_passes(llmod, optimize);
7174-
7175-
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
7176-
llvm.LLVMDisposeModule(llmod);
7188+
run_passes(llmod, optimize, output, ot);
71777189
}
71787190

71797191
//

src/rustllvm/RustWrapper.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,18 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15+
#include "llvm/PassManager.h"
16+
#include "llvm/ADT/Triple.h"
17+
#include "llvm/Support/FormattedStream.h"
18+
#include "llvm/Target/TargetMachine.h"
19+
#include "llvm/Target/TargetSelect.h"
20+
#include "llvm/Target/TargetRegistry.h"
1521
#include "llvm-c/Core.h"
1622
#include "llvm-c/Object.h"
1723
#include <cstdlib>
1824

25+
using namespace llvm;
26+
1927
static char *LLVMRustError;
2028

2129
extern "C" LLVMMemoryBufferRef
@@ -33,3 +41,24 @@ extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
3341

3442
void (*RustHackToFetchPassesO)(LLVMPassManagerRef PM) =
3543
LLVMAddBasicAliasAnalysisPass;
44+
45+
extern "C" void LLVMRustWriteAssembly(LLVMPassManagerRef PMR, LLVMModuleRef M,
46+
const char *triple, const char *path) {
47+
InitializeAllTargets();
48+
InitializeAllAsmPrinters();
49+
std::string Err;
50+
const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err);
51+
std::string FeaturesStr;
52+
TargetMachine &Target = *TheTarget->createTargetMachine(triple, FeaturesStr);
53+
bool NoVerify = false;
54+
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
55+
TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_AssemblyFile;
56+
PassManager *PM = unwrap<PassManager>(PMR);
57+
std::string ErrorInfo;
58+
raw_fd_ostream OS(path, ErrorInfo,
59+
raw_fd_ostream::F_Binary);
60+
formatted_raw_ostream FOS(OS);
61+
bool foo = Target.addPassesToEmitFile(*PM, FOS, FileType, OLvl, NoVerify);
62+
assert(!foo);
63+
PM->run(*unwrap(M));
64+
}

src/rustllvm/rustllvm.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
LLVMRustCreateMemoryBufferWithContentsOfFile
2+
LLVMRustWriteAssembly
23
LLVMRustGetLastError
34
LLVMCreateObjectFile
45
LLVMDisposeObjectFile

0 commit comments

Comments
 (0)