auto merge of #5044 : thestinger/rust/range, r=pcwalton
Closes #4924 There are some more `Load` calls that could use this, so it's not completely done yet.
This commit is contained in:
commit
db25210244
4 changed files with 55 additions and 4 deletions
|
|
@ -184,6 +184,15 @@ pub enum FileType {
|
|||
ObjectFile = 1
|
||||
}
|
||||
|
||||
pub enum Metadata {
|
||||
MD_dbg = 0,
|
||||
MD_tbaa = 1,
|
||||
MD_prof = 2,
|
||||
MD_fpmath = 3,
|
||||
MD_range = 4,
|
||||
MD_tbaa_struct = 5
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
pub enum Module_opaque {}
|
||||
pub type ModuleRef = *Module_opaque;
|
||||
|
|
|
|||
|
|
@ -1361,13 +1361,29 @@ pub fn compile_submatch(bcx: block,
|
|||
if opts.len() > 0u {
|
||||
match opts[0] {
|
||||
var(_, vdef) => {
|
||||
if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u {
|
||||
let variants = ty::enum_variants(tcx, vdef.enm);
|
||||
if variants.len() == 1 {
|
||||
kind = single;
|
||||
} else {
|
||||
let enumptr =
|
||||
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
|
||||
let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
|
||||
test_val = Load(bcx, discrimptr);
|
||||
|
||||
|
||||
assert variants.len() > 1;
|
||||
let min_discrim = do variants.foldr(0) |&x, y| {
|
||||
int::min(x.disr_val, y)
|
||||
};
|
||||
let max_discrim = do variants.foldr(0) |&x, y| {
|
||||
int::max(x.disr_val, y)
|
||||
};
|
||||
|
||||
test_val = LoadRangeAssert(bcx, discrimptr,
|
||||
min_discrim as c_ulonglong,
|
||||
(max_discrim + 1)
|
||||
as c_ulonglong,
|
||||
lib::llvm::True);
|
||||
|
||||
kind = switch;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ use lib::llvm::llvm;
|
|||
use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering};
|
||||
use lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False};
|
||||
use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||
use libc::{c_uint, c_int};
|
||||
use libc::{c_uint, c_int, c_ulonglong};
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::machine::llsize_of_real;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::cast;
|
||||
|
|
@ -536,6 +537,25 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
|
||||
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
|
||||
let value = Load(cx, PointerVal);
|
||||
|
||||
unsafe {
|
||||
let t = llvm::LLVMGetElementType(llvm::LLVMTypeOf(PointerVal));
|
||||
let min = llvm::LLVMConstInt(t, lo, signed);
|
||||
let max = llvm::LLVMConstInt(t, hi, signed);
|
||||
|
||||
|
||||
do vec::as_imm_buf([min, max]) |ptr, len| {
|
||||
llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
|
||||
llvm::LLVMMDNode(ptr, len as c_uint));
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
|
||||
unsafe {
|
||||
if cx.unreachable { return; }
|
||||
|
|
|
|||
|
|
@ -431,7 +431,13 @@ pub impl Datum {
|
|||
} else {
|
||||
match self.mode {
|
||||
ByValue => self.val,
|
||||
ByRef => Load(bcx, self.val)
|
||||
ByRef => {
|
||||
if ty::type_is_bool(self.ty) {
|
||||
LoadRangeAssert(bcx, self.val, 0, 2, lib::llvm::True)
|
||||
} else {
|
||||
Load(bcx, self.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue