Skip to content

Commit 9a188b2

Browse files
committed
rustc: Fall back to intrinsics.ll if we can't parse the bc
This will allow us to transition to the new bitcode format.
1 parent 143f878 commit 9a188b2

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

src/comp/back/link.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,64 @@ fn llvm_err(sess: session::session, msg: str) unsafe {
3737
} else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); }
3838
}
3939

40-
fn link_intrinsics(sess: session::session, llmod: ModuleRef) {
40+
fn load_intrinsics_bc(sess: session::session) -> option::t<ModuleRef> {
4141
let path = alt filesearch::search(
4242
sess.filesearch(),
4343
bind filesearch::pick_file("intrinsics.bc", _)) {
4444
option::some(path) { path }
45-
option::none. { sess.fatal("couldn't find intrinsics.bc") }
45+
option::none. {
46+
sess.warn("couldn't find intrinsics.bc");
47+
ret option::none;
48+
}
4649
};
4750
let membuf = str::as_buf(path, {|buf|
4851
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
49-
});
52+
});
5053
if membuf as uint == 0u {
5154
llvm_err(sess, "installation problem: couldn't open " + path);
5255
fail;
5356
}
5457
let llintrinsicsmod = llvm::LLVMRustParseBitcode(membuf);
5558
llvm::LLVMDisposeMemoryBuffer(membuf);
5659
if llintrinsicsmod as uint == 0u {
57-
llvm_err(sess, "installation problem: couldn't parse intrinsics.bc");
60+
sess.warn("couldn't parse intrinsics.bc");
61+
ret option::none;
62+
}
63+
64+
ret option::some(llintrinsicsmod);
65+
}
66+
67+
fn load_intrinsics_ll(sess: session::session) -> ModuleRef {
68+
let path = alt filesearch::search(
69+
sess.filesearch(),
70+
bind filesearch::pick_file("intrinsics.ll", _)) {
71+
option::some(path) { path }
72+
option::none. { sess.fatal("couldn't find intrinsics.ll") }
73+
};
74+
let llintrinsicsmod = str::as_buf(path, { |buf|
75+
llvm::LLVMRustParseAssemblyFile(buf)
76+
});
77+
if llintrinsicsmod as uint == 0u {
78+
llvm_err(sess, "couldn't parse intrinsics.ll");
5879
fail;
5980
}
81+
ret llintrinsicsmod;
82+
}
83+
84+
fn link_intrinsics(sess: session::session, llmod: ModuleRef) {
85+
let llintrinsicsmod = {
86+
alt load_intrinsics_bc(sess) {
87+
option::some(m) { m }
88+
option::none. {
89+
// When the bitcode format changes we can't parse a .bc
90+
// file produced with a newer LLVM (as happens when stage0
91+
// is trying to build against a new LLVM revision), in
92+
// that case we'll try to parse the assembly.
93+
sess.warn("couldn't parse intrinsics.bc, trying intrinsics.ll");
94+
load_intrinsics_ll(sess)
95+
}
96+
}
97+
};
6098
let linkres = llvm::LLVMLinkModules(llmod, llintrinsicsmod);
6199
llvm::LLVMDisposeModule(llintrinsicsmod);
62100
if linkres == False {

src/comp/lib/llvm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,9 @@ native mod llvm {
864864
/** Parses the bitcode in the given memory buffer. */
865865
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
866866

867+
/** Parses LLVM asm in the given file */
868+
fn LLVMRustParseAssemblyFile(Filename: sbuf) -> ModuleRef;
869+
867870
/** FiXME: Hacky adaptor for lack of ULongLong in FFI: */
868871
fn LLVMRustConstInt(IntTy: TypeRef, N_hi: uint, N_lo: uint,
869872
SignExtend: Bool) -> ValueRef;

src/rustllvm/RustWrapper.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@
1212
//
1313
//===----------------------------------------------------------------------===
1414

15+
#include "llvm/LLVMContext.h"
1516
#include "llvm/Linker.h"
1617
#include "llvm/PassManager.h"
1718
#include "llvm/ADT/Triple.h"
19+
#include "llvm/Assembly/Parser.h"
1820
#include "llvm/Assembly/PrintModulePass.h"
1921
#include "llvm/Support/FormattedStream.h"
2022
#include "llvm/Support/Timer.h"
2123
#include "llvm/Support/raw_ostream.h"
2224
#include "llvm/Target/TargetMachine.h"
2325
#include "llvm/Support/TargetSelect.h"
2426
#include "llvm/Support/TargetRegistry.h"
27+
#include "llvm/Support/SourceMgr.h"
2528
#include "llvm/Target/TargetOptions.h"
2629
#include "llvm/Support/Host.h"
2730
#include "llvm-c/Core.h"
@@ -109,6 +112,18 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
109112
delete Target;
110113
}
111114

115+
extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(const char *Filename) {
116+
117+
SMDiagnostic d;
118+
Module *m = ParseAssemblyFile(Filename, d, getGlobalContext());
119+
if (m) {
120+
return wrap(m);
121+
} else {
122+
LLVMRustError = d.getMessage().c_str();
123+
return NULL;
124+
}
125+
}
126+
112127
extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) {
113128
LLVMModuleRef M;
114129
return LLVMParseBitcode(MemBuf, &M, const_cast<char **>(&LLVMRustError))

src/rustllvm/rustllvm.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LLVMRustGetHostTriple
66
LLVMRustConstSmallInt
77
LLVMRustConstInt
88
LLVMRustParseBitcode
9+
LLVMRustParseAssemblyFile
910
LLVMRustPrintPassTimings
1011
LLVMRustEnableSegmentedStacks
1112
LLVMLinkModules

0 commit comments

Comments
 (0)