Remove source line generation craziness. Ensure incorrect subprogram caches are not conflated. Generate ast_map entries for object members and resource constructors and destructors.
This commit is contained in:
parent
c6f16ed2c4
commit
df6052c4f8
6 changed files with 174 additions and 392 deletions
|
|
@ -7,6 +7,7 @@ import syntax::{visit, codemap};
|
|||
tag ast_node {
|
||||
node_item(@item);
|
||||
node_obj_ctor(@item);
|
||||
node_obj_method(@method);
|
||||
node_native_item(@native_item);
|
||||
node_method(@method);
|
||||
node_expr(@expr);
|
||||
|
|
@ -14,6 +15,7 @@ tag ast_node {
|
|||
// order they are introduced.
|
||||
node_arg(arg, uint);
|
||||
node_local(uint);
|
||||
node_res_ctor(@item);
|
||||
}
|
||||
|
||||
type map = std::map::hashmap<node_id, ast_node>;
|
||||
|
|
@ -63,9 +65,17 @@ fn map_arm(cx: ctx, arm: arm) {
|
|||
fn map_item(cx: ctx, i: @item) {
|
||||
cx.map.insert(i.id, node_item(i));
|
||||
alt i.node {
|
||||
item_obj(_, _, ctor_id) { cx.map.insert(ctor_id, node_obj_ctor(i)); }
|
||||
item_obj(ob, _, ctor_id) {
|
||||
cx.map.insert(ctor_id, node_obj_ctor(i));
|
||||
for m in ob.methods {
|
||||
cx.map.insert(m.node.id, node_obj_method(m));
|
||||
}
|
||||
}
|
||||
item_impl(_, _, ms) {
|
||||
for m in ms { cx.map.insert(m.node.id, node_method(m)); }
|
||||
item_res(_, dtor_id, _, ctor_id) {
|
||||
cx.map.insert(ctor_id, node_res_ctor(i));
|
||||
cx.map.insert(dtor_id, node_item(i));
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import util::ppaux::ty_to_str;
|
|||
export create_local_var;
|
||||
export create_function;
|
||||
export create_arg;
|
||||
export add_line_info;
|
||||
export update_source_pos;
|
||||
export invalidate_source_pos;
|
||||
export revalidate_source_pos;
|
||||
export debug_ctxt;
|
||||
|
||||
const LLVMDebugVersion: int = (9 << 16);
|
||||
|
|
@ -98,7 +95,7 @@ type metadata<T> = {node: ValueRef, data: T};
|
|||
|
||||
type file_md = {path: str};
|
||||
type compile_unit_md = {path: str};
|
||||
type subprogram_md = {name: str, file: str};
|
||||
type subprogram_md = {path: str};
|
||||
type local_var_md = {id: ast::node_id};
|
||||
type tydesc_md = {hash: uint};
|
||||
type block_md = {start: codemap::loc, end: codemap::loc};
|
||||
|
|
@ -232,7 +229,7 @@ fn create_block(cx: @block_ctxt) -> @metadata<block_md> {
|
|||
}
|
||||
|
||||
let parent = alt cx.parent {
|
||||
trans_common::parent_none. { function_metadata_from_block(cx).node }
|
||||
trans_common::parent_none. { create_function(cx.fcx).node }
|
||||
trans_common::parent_some(bcx) { create_block(cx).node }
|
||||
};
|
||||
let file_node = create_file(bcx_ccx(cx), fname);
|
||||
|
|
@ -595,14 +592,6 @@ fn create_ty(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata<tydesc_md> {
|
|||
};
|
||||
}
|
||||
|
||||
fn function_metadata_from_block(bcx: @block_ctxt) -> @metadata<subprogram_md> {
|
||||
let cx = bcx_ccx(bcx);
|
||||
let fcx = bcx_fcx(bcx);
|
||||
let fn_node = cx.ast_map.get(fcx.id);
|
||||
let fn_item = alt fn_node { ast_map::node_item(item) { item } };
|
||||
ret create_function(fcx, fn_item, fcx.llfn);
|
||||
}
|
||||
|
||||
fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> str {
|
||||
codemap::lookup_char_pos(cx.sess.get_codemap(), sp.lo).filename
|
||||
}
|
||||
|
|
@ -640,7 +629,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local)
|
|||
let tymd = create_ty(cx, ty, local.node.ty);
|
||||
let filemd = create_file(cx, loc.filename);
|
||||
let context = alt bcx.parent {
|
||||
trans_common::parent_none. { function_metadata_from_block(bcx).node }
|
||||
trans_common::parent_none. { create_function(bcx.fcx).node }
|
||||
trans_common::parent_some(_) { create_block(bcx).node }
|
||||
};
|
||||
let mdnode = create_var(tg, context, name, filemd.node,
|
||||
|
|
@ -662,7 +651,6 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local)
|
|||
ret mdval;
|
||||
}
|
||||
|
||||
//FIXME: consolidate with create_local_var
|
||||
fn create_arg(bcx: @block_ctxt, arg: ast::arg)
|
||||
-> @metadata<argument_md> unsafe {
|
||||
let fcx = bcx_fcx(bcx);
|
||||
|
|
@ -683,9 +671,7 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg)
|
|||
let ty = trans::node_id_type(cx, arg.id);
|
||||
let tymd = create_ty(cx, ty, arg.ty);
|
||||
let filemd = create_file(cx, loc.filename);
|
||||
let fn_node = cx.ast_map.get(fcx.id);
|
||||
let fn_item = alt fn_node { ast_map::node_item(item) { item } };
|
||||
let context = create_function(fcx, fn_item, fcx.llfn);
|
||||
let context = create_function(bcx.fcx);
|
||||
let mdnode = create_var(tg, context.node, arg.ident, filemd.node,
|
||||
loc.line as int, tymd.node);
|
||||
let mdval = @{node: mdnode, data: {id: arg.id}};
|
||||
|
|
@ -700,92 +686,76 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg)
|
|||
ret mdval;
|
||||
}
|
||||
|
||||
fn update_source_pos(cx: @block_ctxt, s: codemap::span) -> @debug_source_pos {
|
||||
let dsp = @debug_source_pos(cx);
|
||||
fn update_source_pos(cx: @block_ctxt, s: codemap::span) {
|
||||
if !bcx_ccx(cx).sess.get_opts().debuginfo {
|
||||
ret dsp;
|
||||
ret;
|
||||
}
|
||||
let cm = bcx_ccx(cx).sess.get_codemap();
|
||||
if vec::is_empty(cx.source_pos.pos) {
|
||||
cx.source_pos.usable = true;
|
||||
}
|
||||
cx.source_pos.pos += [codemap::lookup_char_pos(cm, s.lo)]; //XXX maybe hi
|
||||
ret dsp;
|
||||
}
|
||||
|
||||
fn invalidate_source_pos(cx: @block_ctxt) -> @invalidated_source_pos {
|
||||
let isp = @invalidated_source_pos(cx);
|
||||
if !bcx_ccx(cx).sess.get_opts().debuginfo {
|
||||
ret isp;
|
||||
}
|
||||
cx.source_pos.usable = false;
|
||||
ret isp;
|
||||
}
|
||||
|
||||
fn revalidate_source_pos(cx: @block_ctxt) {
|
||||
if !bcx_ccx(cx).sess.get_opts().debuginfo {
|
||||
ret;
|
||||
}
|
||||
cx.source_pos.usable = true;
|
||||
}
|
||||
|
||||
fn reset_source_pos(cx: @block_ctxt) {
|
||||
if !bcx_ccx(cx).sess.get_opts().debuginfo {
|
||||
ret;
|
||||
}
|
||||
vec::pop(cx.source_pos.pos);
|
||||
}
|
||||
|
||||
resource debug_source_pos(bcx: @block_ctxt) {
|
||||
reset_source_pos(bcx);
|
||||
}
|
||||
resource invalidated_source_pos(bcx: @block_ctxt) {
|
||||
revalidate_source_pos(bcx);
|
||||
}
|
||||
|
||||
fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) {
|
||||
if !bcx_ccx(cx).sess.get_opts().debuginfo ||
|
||||
!cx.source_pos.usable ||
|
||||
vec::is_empty(cx.source_pos.pos) {
|
||||
ret;
|
||||
}
|
||||
let loc = option::get(vec::last(cx.source_pos.pos));
|
||||
let blockmd = create_block(cx);
|
||||
let kind = "dbg";
|
||||
str::as_buf(kind, {|sbuf|
|
||||
let kind_id = llvm::LLVMGetMDKindID(sbuf,
|
||||
str::byte_len(kind));
|
||||
let scopedata = [lli32(loc.line as int),
|
||||
lli32(loc.col as int),
|
||||
blockmd.node,
|
||||
llnull()];
|
||||
let dbgscope = llmdnode(scopedata);
|
||||
llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope)
|
||||
});
|
||||
let loc = codemap::lookup_char_pos(cm, s.lo);
|
||||
let scopedata = [lli32(loc.line as int),
|
||||
lli32(loc.col as int),
|
||||
blockmd.node,
|
||||
llnull()];
|
||||
let dbgscope = llmdnode(scopedata);
|
||||
llvm::LLVMSetCurrentDebugLocation(trans_build::B(cx), dbgscope);
|
||||
}
|
||||
|
||||
fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef)
|
||||
-> @metadata<subprogram_md> {
|
||||
fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
|
||||
let cx = fcx_ccx(fcx);
|
||||
let dbg_cx = option::get(cx.dbg_cx);
|
||||
|
||||
log "~~";
|
||||
log fcx.id;
|
||||
log cx.sess.span_str(fcx.sp);
|
||||
|
||||
let (ident, ret_ty, id) = alt cx.ast_map.get(fcx.id) {
|
||||
ast_map::node_item(item) {
|
||||
alt item.node {
|
||||
ast::item_fn(f, _) | ast::item_res(f, _, _, _) {
|
||||
(item.ident, f.decl.output, item.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_map::node_obj_method(method) {
|
||||
(method.node.ident, method.node.meth.decl.output, method.node.id)
|
||||
}
|
||||
ast_map::node_res_ctor(item) {
|
||||
alt item.node { ast::item_res(f, _, _, ctor_id) {
|
||||
(item.ident, f.decl.output, ctor_id)
|
||||
}}
|
||||
}
|
||||
ast_map::node_expr(expr) {
|
||||
alt expr.node {
|
||||
ast::expr_fn(f) {
|
||||
(dbg_cx.names.next("fn"), f.decl.output, expr.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
log ident;
|
||||
log id;
|
||||
|
||||
let path = str::connect(fcx.lcx.path + [ident], "::");
|
||||
|
||||
let cache = get_cache(cx);
|
||||
alt cached_metadata::<@metadata<subprogram_md>>(
|
||||
cache, SubprogramTag, {|md| md.data.name == item.ident &&
|
||||
cache, SubprogramTag, {|md| md.data.path == path &&
|
||||
/*md.data.path == ??*/ true}) {
|
||||
option::some(md) { ret md; }
|
||||
option::none. {}
|
||||
}
|
||||
|
||||
let loc = codemap::lookup_char_pos(cx.sess.get_codemap(),
|
||||
item.span.lo);
|
||||
fcx.sp.lo);
|
||||
let file_node = create_file(cx, loc.filename).node;
|
||||
let mangled = cx.item_symbols.get(item.id);
|
||||
let ret_ty = alt item.node {
|
||||
ast::item_fn(f, _) { f.decl.output }
|
||||
};
|
||||
let key = cx.item_symbols.contains_key(fcx.id) ? fcx.id : id;
|
||||
let mangled = cx.item_symbols.get(key);
|
||||
let ty_node = if cx.sess.get_opts().extra_debuginfo {
|
||||
alt ret_ty.node {
|
||||
ast::ty_nil. { llnull() }
|
||||
_ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), item.id),
|
||||
_ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), id),
|
||||
ret_ty).node }
|
||||
}
|
||||
} else {
|
||||
|
|
@ -798,8 +768,8 @@ fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef)
|
|||
let fn_metadata = [lltag(SubprogramTag),
|
||||
llunused(),
|
||||
file_node,
|
||||
llstr(item.ident),
|
||||
llstr(item.ident), //XXX fully-qualified C++ name
|
||||
llstr(ident),
|
||||
llstr(path), //XXX fully-qualified C++ name
|
||||
llstr(mangled), //XXX MIPS name?????
|
||||
file_node,
|
||||
lli32(loc.line as int),
|
||||
|
|
@ -811,15 +781,14 @@ fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef)
|
|||
llnull(), // base type with vtbl
|
||||
lli1(false), // artificial
|
||||
lli1(cx.sess.get_opts().optimize != 0u),
|
||||
llfndecl
|
||||
fcx.llfn
|
||||
//list of template params
|
||||
//func decl descriptor
|
||||
//list of func vars
|
||||
];
|
||||
let val = llmdnode(fn_metadata);
|
||||
add_named_metadata(cx, "llvm.dbg.sp", val);
|
||||
let mdval = @{node: val, data: {name: item.ident,
|
||||
file: loc.filename}};
|
||||
let mdval = @{node: val, data: {path: path}};
|
||||
update_cache(cache, SubprogramTag, subprogram_metadata(mdval));
|
||||
ret mdval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3519,7 +3519,7 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result {
|
|||
// - exprs with non-immediate type never get dest=by_val
|
||||
fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
||||
let tcx = bcx_tcx(bcx);
|
||||
let _s = debuginfo::update_source_pos(bcx, e.span);
|
||||
debuginfo::update_source_pos(bcx, e.span);
|
||||
|
||||
if expr_is_lval(bcx, e) {
|
||||
ret lval_to_dps(bcx, e, dest);
|
||||
|
|
@ -4014,7 +4014,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt {
|
|||
}
|
||||
|
||||
let bcx = cx;
|
||||
let _s = debuginfo::update_source_pos(cx, s.span);
|
||||
debuginfo::update_source_pos(cx, s.span);
|
||||
|
||||
alt s.node {
|
||||
ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); }
|
||||
|
|
@ -4041,19 +4041,6 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt {
|
|||
ret bcx;
|
||||
}
|
||||
|
||||
fn source_pos_from_block_parent(parent: block_parent)
|
||||
-> (bool, [codemap::loc]) {
|
||||
alt parent {
|
||||
parent_none. { (false, []) }
|
||||
parent_some(bcx) { (bcx.source_pos.usable,
|
||||
alt vec::last(bcx.source_pos.pos) {
|
||||
option::some(p) { [p] }
|
||||
option::none. { [] }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// You probably don't want to use this one. See the
|
||||
// next three functions instead.
|
||||
fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
|
||||
|
|
@ -4065,7 +4052,6 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
|
|||
}
|
||||
let llbb: BasicBlockRef =
|
||||
str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) });
|
||||
let (usable, pos) = source_pos_from_block_parent(parent);
|
||||
let bcx = @{llbb: llbb,
|
||||
mutable terminated: false,
|
||||
mutable unreachable: false,
|
||||
|
|
@ -4075,8 +4061,7 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
|
|||
mutable lpad_dirty: true,
|
||||
mutable lpad: option::none,
|
||||
sp: cx.sp,
|
||||
fcx: cx,
|
||||
source_pos: {mutable usable: usable, mutable pos: pos}};
|
||||
fcx: cx};
|
||||
alt parent {
|
||||
parent_some(cx) {
|
||||
if cx.unreachable { Unreachable(bcx); }
|
||||
|
|
@ -4111,7 +4096,6 @@ fn new_sub_block_ctxt(bcx: @block_ctxt, n: str) -> @block_ctxt {
|
|||
}
|
||||
|
||||
fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt {
|
||||
let (usable, pos) = source_pos_from_block_parent(parent_none);
|
||||
ret @{llbb: llbb,
|
||||
mutable terminated: false,
|
||||
mutable unreachable: false,
|
||||
|
|
@ -4121,8 +4105,7 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt {
|
|||
mutable lpad_dirty: true,
|
||||
mutable lpad: option::none,
|
||||
sp: fcx.sp,
|
||||
fcx: fcx,
|
||||
source_pos: {mutable usable: usable, mutable pos: pos}};
|
||||
fcx: fcx};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4180,7 +4163,6 @@ fn block_locals(b: ast::blk, it: block(@ast::local)) {
|
|||
}
|
||||
|
||||
fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
|
||||
let (usable, pos) = source_pos_from_block_parent(parent_none);
|
||||
ret @{llbb: fcx.llstaticallocas,
|
||||
mutable terminated: false,
|
||||
mutable unreachable: false,
|
||||
|
|
@ -4190,12 +4172,10 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
|
|||
mutable lpad_dirty: true,
|
||||
mutable lpad: option::none,
|
||||
sp: fcx.sp,
|
||||
fcx: fcx,
|
||||
source_pos: {mutable usable: usable, mutable pos: pos}};
|
||||
fcx: fcx};
|
||||
}
|
||||
|
||||
fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
|
||||
let (usable, pos) = source_pos_from_block_parent(parent_none);
|
||||
ret @{llbb: fcx.llderivedtydescs,
|
||||
mutable terminated: false,
|
||||
mutable unreachable: false,
|
||||
|
|
@ -4205,8 +4185,7 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
|
|||
mutable lpad_dirty: true,
|
||||
mutable lpad: option::none,
|
||||
sp: fcx.sp,
|
||||
fcx: fcx,
|
||||
source_pos: {mutable usable: usable, mutable pos: pos}};
|
||||
fcx: fcx};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4281,13 +4260,13 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest)
|
|||
let bcx = bcx;
|
||||
block_locals(b) {|local| bcx = alloc_local(bcx, local); };
|
||||
for s: @ast::stmt in b.node.stmts {
|
||||
let _s = debuginfo::update_source_pos(bcx, b.span);
|
||||
debuginfo::update_source_pos(bcx, b.span);
|
||||
bcx = trans_stmt(bcx, *s);
|
||||
}
|
||||
alt b.node.expr {
|
||||
some(e) {
|
||||
let bt = ty::type_is_bot(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e));
|
||||
let _s = debuginfo::update_source_pos(bcx, e.span);
|
||||
debuginfo::update_source_pos(bcx, e.span);
|
||||
bcx = trans_expr(bcx, e, bt ? ignore : dest);
|
||||
}
|
||||
_ { assert dest == ignore || bcx.unreachable; }
|
||||
|
|
@ -4585,10 +4564,7 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
|
|||
let fcx = option::none;
|
||||
trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id, {|new_fcx| fcx = option::some(new_fcx);});
|
||||
if cx.ccx.sess.get_opts().extra_debuginfo {
|
||||
let item = alt option::get(cx.ccx.ast_map.find(id)) {
|
||||
ast_map::node_item(item) { item }
|
||||
};
|
||||
debuginfo::create_function(option::get(fcx), item, llfndecl);
|
||||
debuginfo::create_function(option::get(fcx));
|
||||
}
|
||||
if do_time {
|
||||
let end = time::get_time();
|
||||
|
|
|
|||
|
|
@ -25,16 +25,14 @@ fn RetVoid(cx: @block_ctxt) {
|
|||
if cx.unreachable { ret; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildRetVoid(B(cx));
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildRetVoid(B(cx));
|
||||
}
|
||||
|
||||
fn Ret(cx: @block_ctxt, V: ValueRef) {
|
||||
if cx.unreachable { ret; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildRet(B(cx), V);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildRet(B(cx), V);
|
||||
}
|
||||
|
||||
fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) {
|
||||
|
|
@ -42,9 +40,8 @@ fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) {
|
|||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
unsafe {
|
||||
let instr = llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals),
|
||||
vec::len(RetVals));
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals),
|
||||
vec::len(RetVals));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,8 +49,7 @@ fn Br(cx: @block_ctxt, Dest: BasicBlockRef) {
|
|||
if cx.unreachable { ret; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildBr(B(cx), Dest);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildBr(B(cx), Dest);
|
||||
}
|
||||
|
||||
fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
||||
|
|
@ -61,8 +57,7 @@ fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
|||
if cx.unreachable { ret; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
||||
}
|
||||
|
||||
fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
||||
|
|
@ -70,9 +65,7 @@ fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
|||
if cx.unreachable { ret _Undef(V); }
|
||||
assert !cx.terminated;
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases);
|
||||
}
|
||||
|
||||
fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
|
||||
|
|
@ -84,8 +77,7 @@ fn IndirectBr(cx: @block_ctxt, Addr: ValueRef, NumDests: uint) {
|
|||
if cx.unreachable { ret; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests);
|
||||
}
|
||||
|
||||
// This is a really awful way to get a zero-length c-string, but better (and a
|
||||
|
|
@ -105,14 +97,10 @@ fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
|||
vec::len(Args), Then, Catch,
|
||||
noname());
|
||||
if bcx_ccx(cx).sess.get_opts().debuginfo {
|
||||
/*llvm::LLVMAddAttribute(option::get(vec::last(llargs)),
|
||||
lib::llvm::LLVMStructRetAttribute as
|
||||
lib::llvm::llvm::Attribute);*/
|
||||
llvm::LLVMAddInstrAttribute(instr, 1u,
|
||||
lib::llvm::LLVMStructRetAttribute as
|
||||
lib::llvm::llvm::Attribute);
|
||||
}
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +113,6 @@ fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
|||
let v = llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), Then, Catch, noname());
|
||||
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
||||
debuginfo::add_line_info(cx, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,254 +129,183 @@ fn _Undef(val: ValueRef) -> ValueRef {
|
|||
/* Arithmetic */
|
||||
fn Add(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Sub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Mul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn UDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn SDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn ExactSDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn URem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn SRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Shl(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn LShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn AShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn And(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Or(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Xor(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn BinOp(cx: @block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret _Undef(LHS); }
|
||||
let instr = llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Neg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(V); }
|
||||
let instr = llvm::LLVMBuildNeg(B(cx), V, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn NSWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(V); }
|
||||
let instr = llvm::LLVMBuildNSWNeg(B(cx), V, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNSWNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn NUWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(V); }
|
||||
let instr = llvm::LLVMBuildNUWNeg(B(cx), V, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNUWNeg(B(cx), V, noname());
|
||||
}
|
||||
fn FNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(V); }
|
||||
let instr = llvm::LLVMBuildFNeg(B(cx), V, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn Not(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret _Undef(V); }
|
||||
let instr = llvm::LLVMBuildNot(B(cx), V, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildNot(B(cx), V, noname());
|
||||
}
|
||||
|
||||
/* Memory */
|
||||
fn Malloc(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
let instr = llvm::LLVMBuildMalloc(B(cx), Ty, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildMalloc(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
fn ArrayMalloc(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
let instr = llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
|
||||
}
|
||||
|
||||
fn Alloca(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||
let instr = llvm::LLVMBuildAlloca(B(cx), Ty, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildAlloca(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
fn ArrayAlloca(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||
let instr = llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
|
||||
}
|
||||
|
||||
fn Free(cx: @block_ctxt, PointerVal: ValueRef) {
|
||||
if cx.unreachable { ret; }
|
||||
let instr = llvm::LLVMBuildFree(B(cx), PointerVal);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildFree(B(cx), PointerVal);
|
||||
}
|
||||
|
||||
fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
||||
|
|
@ -400,24 +316,19 @@ fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
|||
llvm::LLVMGetElementType(ty) } else { ccx.int_type };
|
||||
ret llvm::LLVMGetUndef(eltty);
|
||||
}
|
||||
let instr = llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
||||
}
|
||||
|
||||
fn Store(cx: @block_ctxt, Val: ValueRef, Ptr: ValueRef) {
|
||||
if cx.unreachable { ret; }
|
||||
let instr = llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
||||
}
|
||||
|
||||
fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
unsafe {
|
||||
let instr = llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
||||
vec::len(Indices), noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
||||
vec::len(Indices), noname());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -433,195 +344,143 @@ fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) ->
|
|||
ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
unsafe {
|
||||
let instr = llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
|
||||
vec::to_ptr(Indices),
|
||||
vec::len(Indices), noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
|
||||
vec::to_ptr(Indices),
|
||||
vec::len(Indices), noname());
|
||||
}
|
||||
}
|
||||
|
||||
fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
let instr = llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname());
|
||||
}
|
||||
|
||||
fn GlobalString(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
let instr = llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
||||
}
|
||||
|
||||
fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
let instr = llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
||||
}
|
||||
|
||||
/* Casts */
|
||||
fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
||||
_Name: sbuf) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||
let instr = llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
|
||||
//debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
|
||||
/* Comparisons */
|
||||
fn ICmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||
let instr = llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FCmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||
let instr = llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
fn EmptyPhi(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
||||
let instr = llvm::LLVMBuildPhi(B(cx), Ty, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildPhi(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
fn Phi(cx: @block_ctxt, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef])
|
||||
|
|
@ -656,7 +515,9 @@ fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef {
|
|||
fn add_span_comment(bcx: @block_ctxt, sp: span, text: str) {
|
||||
let ccx = bcx_ccx(bcx);
|
||||
if (!ccx.sess.get_opts().no_asm_comments) {
|
||||
add_comment(bcx, text + " (" + ccx.sess.span_str(sp) + ")");
|
||||
let s = text + " (" + ccx.sess.span_str(sp) + ")";
|
||||
log s;
|
||||
add_comment(bcx, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -676,10 +537,8 @@ fn add_comment(bcx: @block_ctxt, text: str) {
|
|||
fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
||||
unsafe {
|
||||
let instr = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -689,7 +548,6 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
|||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
||||
debuginfo::add_line_info(cx, v);
|
||||
ret v;
|
||||
}
|
||||
}
|
||||
|
|
@ -701,7 +559,6 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint)
|
|||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
llvm::LLVMSetInstructionCallConv(v, Conv);
|
||||
debuginfo::add_line_info(cx, v);
|
||||
ret v;
|
||||
}
|
||||
}
|
||||
|
|
@ -709,76 +566,57 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint)
|
|||
fn Select(cx: @block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret _Undef(Then); }
|
||||
let instr = llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
|
||||
}
|
||||
|
||||
fn VAArg(cx: @block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
||||
let instr = llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
|
||||
}
|
||||
|
||||
fn ExtractElement(cx: @block_ctxt, VecVal: ValueRef, Index: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
||||
let instr = llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
|
||||
}
|
||||
|
||||
fn InsertElement(cx: @block_ctxt, VecVal: ValueRef, EltVal: ValueRef,
|
||||
Index: ValueRef) {
|
||||
if cx.unreachable { ret; }
|
||||
let instr = llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index,
|
||||
noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
|
||||
}
|
||||
|
||||
fn ShuffleVector(cx: @block_ctxt, V1: ValueRef, V2: ValueRef,
|
||||
Mask: ValueRef) {
|
||||
if cx.unreachable { ret; }
|
||||
let instr = llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
|
||||
}
|
||||
|
||||
fn ExtractValue(cx: @block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
||||
let instr = llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname());
|
||||
}
|
||||
|
||||
fn InsertValue(cx: @block_ctxt, AggVal: ValueRef, EltVal: ValueRef,
|
||||
Index: uint) {
|
||||
if cx.unreachable { ret; }
|
||||
let instr = llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index,
|
||||
noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, noname());
|
||||
}
|
||||
|
||||
fn IsNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||
let instr = llvm::LLVMBuildIsNull(B(cx), Val, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildIsNull(B(cx), Val, noname());
|
||||
}
|
||||
|
||||
fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||
let instr = llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
|
||||
}
|
||||
|
||||
fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
let ccx = cx.fcx.lcx.ccx;
|
||||
if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); }
|
||||
let instr = llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Trap(cx: @block_ctxt) {
|
||||
|
|
@ -793,19 +631,14 @@ fn Trap(cx: @block_ctxt) {
|
|||
assert (T as int != 0);
|
||||
let Args: [ValueRef] = [];
|
||||
unsafe {
|
||||
let instr = llvm::LLVMBuildCall(b, T, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), noname());
|
||||
}
|
||||
}
|
||||
|
||||
fn LandingPad(cx: @block_ctxt, Ty: TypeRef, PersFn: ValueRef,
|
||||
NumClauses: uint) -> ValueRef {
|
||||
assert !cx.terminated && !cx.unreachable;
|
||||
let instr = llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses,
|
||||
noname());
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, noname());
|
||||
}
|
||||
|
||||
fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) {
|
||||
|
|
@ -815,9 +648,7 @@ fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) {
|
|||
fn Resume(cx: @block_ctxt, Exn: ValueRef) -> ValueRef {
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
let instr = llvm::LLVMBuildResume(B(cx), Exn);
|
||||
debuginfo::add_line_info(cx, instr);
|
||||
ret instr;
|
||||
ret llvm::LLVMBuildResume(B(cx), Exn);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -385,9 +385,7 @@ type block_ctxt =
|
|||
mutable lpad_dirty: bool,
|
||||
mutable lpad: option::t<BasicBlockRef>,
|
||||
sp: span,
|
||||
fcx: @fn_ctxt,
|
||||
source_pos: {mutable usable: bool,
|
||||
mutable pos: [syntax::codemap::loc]}};
|
||||
fcx: @fn_ctxt};
|
||||
|
||||
// FIXME: we should be able to use option::t<@block_parent> here but
|
||||
// the infinite-tag check in rustboot gets upset.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ fn pointer_add(bcx: @block_ctxt, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
|||
}
|
||||
|
||||
fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
|
||||
let _s = debuginfo::invalidate_source_pos(bcx);
|
||||
let ccx = bcx_ccx(bcx);
|
||||
let llvecty = ccx.opaque_vec_type;
|
||||
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
|
||||
|
|
@ -46,7 +45,6 @@ type alloc_result =
|
|||
llunitty: TypeRef};
|
||||
|
||||
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
|
||||
let _s = debuginfo::invalidate_source_pos(bcx);
|
||||
let ccx = bcx_ccx(bcx);
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue