Skip to content

Commit 8905343

Browse files
committed
Clean up and refactor some code
* Move the "get the value that will definitely be loaded" logic to it's own method to reduce the duplication. * Refactor base::invoke to avoid duplicating the diverging/zero-sized return logic. * Re-add debugging output I accidentally removed * Add some more comments explaining stuff
1 parent 6187e11 commit 8905343

File tree

4 files changed

+51
-51
lines changed

4 files changed

+51
-51
lines changed

src/librustc_trans/trans/base.rs

+34-50
Original file line numberDiff line numberDiff line change
@@ -728,49 +728,45 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
728728
}
729729
}
730730

731-
if need_invoke(bcx) {
731+
let (mut llresult, bcx) = if need_invoke(bcx) {
732732
debug!("invoking {} at {:?}", bcx.val_to_string(llfn), bcx.llbb);
733733
for &llarg in llargs {
734734
debug!("arg: {}", bcx.val_to_string(llarg));
735735
}
736736
let normal_bcx = bcx.fcx.new_temp_block("normal-return");
737737
let landing_pad = bcx.fcx.get_landing_pad();
738738

739-
let mut llresult = Invoke(bcx,
739+
let llresult = Invoke(bcx,
740740
llfn,
741741
&llargs[..],
742742
normal_bcx.llbb,
743743
landing_pad,
744744
Some(attributes),
745745
debug_loc);
746-
if let ty::FnConverging(ty) = ret_ty {
747-
if return_type_is_void(bcx.ccx(), ty) {
748-
llresult = C_nil(bcx.ccx());
749-
}
750-
} else {
751-
llresult = C_nil(bcx.ccx());
752-
}
753-
return (llresult, normal_bcx);
746+
(llresult, normal_bcx)
754747
} else {
755748
debug!("calling {} at {:?}", bcx.val_to_string(llfn), bcx.llbb);
756749
for &llarg in llargs {
757750
debug!("arg: {}", bcx.val_to_string(llarg));
758751
}
759752

760-
let mut llresult = Call(bcx,
753+
let llresult = Call(bcx,
761754
llfn,
762755
&llargs[..],
763756
Some(attributes),
764757
debug_loc);
765-
if let ty::FnConverging(ty) = ret_ty {
766-
if return_type_is_void(bcx.ccx(), ty) {
767-
llresult = C_nil(bcx.ccx());
768-
}
769-
} else {
758+
(llresult, bcx)
759+
};
760+
761+
if let ty::FnConverging(ty) = ret_ty {
762+
if return_type_is_void(bcx.ccx(), ty) {
770763
llresult = C_nil(bcx.ccx());
771764
}
772-
return (llresult, bcx);
765+
} else {
766+
llresult = C_nil(bcx.ccx());
773767
}
768+
769+
(llresult, bcx)
774770
}
775771

776772
pub fn need_invoke(bcx: Block) -> bool {
@@ -803,41 +799,30 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
803799
/// gives us better information about what we are loading.
804800
pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
805801
ptr: ValueRef, t: Ty<'tcx>) -> ValueRef {
806-
use trans::basic_block::BasicBlock;
807-
808802
if cx.unreachable.get() || type_is_zero_size(cx.ccx(), t) {
809803
return C_undef(type_of::type_of(cx.ccx(), t));
810804
}
811805

812806
let ptr = to_arg_ty_ptr(cx, ptr, t);
813-
let ptr = Value(ptr);
814807
let align = type_of::align_of(cx.ccx(), t);
815808

816-
let bb = BasicBlock(cx.llbb);
817-
818809
if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
819-
if let Some(val) = ptr.get_dominating_store(cx) {
820-
let valbb = val.get_parent();
821-
822-
if Some(bb) == valbb {
823-
if let Some(val) = val.get_operand(0) {
824-
debug!("Eliding load from {}", cx.ccx().tn().val_to_string(ptr.get()));
825-
debug!(" Using previous stored value: {}",
826-
cx.ccx().tn().val_to_string(val.get()));
827-
return val.get();
828-
}
829-
}
810+
if let Some(val) = Value(ptr).get_stored_value_opt(cx) {
811+
debug!("Eliding load from {}", cx.ccx().tn().val_to_string(ptr));
812+
debug!(" Using previous stored value: {}",
813+
cx.ccx().tn().val_to_string(val.get()));
814+
return val.get();
830815
}
831816

832-
let load = Load(cx, ptr.get());
817+
let load = Load(cx, ptr);
833818
unsafe {
834819
llvm::LLVMSetAlignment(load, align);
835820
}
836821
return load;
837822
}
838823

839824
unsafe {
840-
let global = llvm::LLVMIsAGlobalVariable(ptr.get());
825+
let global = llvm::LLVMIsAGlobalVariable(ptr);
841826
if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True {
842827
let val = llvm::LLVMGetInitializer(global);
843828
if !val.is_null() {
@@ -846,30 +831,24 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
846831
}
847832
}
848833

849-
if let Some(val) = ptr.get_dominating_store(cx) {
850-
let valbb = val.get_parent();
851-
852-
if Some(bb) == valbb {
853-
if let Some(val) = val.get_operand(0) {
854-
debug!("Eliding load from {}", cx.ccx().tn().val_to_string(ptr.get()));
855-
debug!(" Using previous stored value: {}",
856-
cx.ccx().tn().val_to_string(val.get()));
857-
return to_arg_ty(cx, val.get(), t);
858-
}
859-
}
834+
if let Some(val) = Value(ptr).get_stored_value_opt(cx) {
835+
debug!("Eliding load from {}", cx.ccx().tn().val_to_string(ptr));
836+
debug!(" Using previous stored value: {}",
837+
cx.ccx().tn().val_to_string(val.get()));
838+
return to_arg_ty(cx, val.get(), t);
860839
}
861840

862841
let val = if t.is_bool() {
863-
LoadRangeAssert(cx, ptr.get(), 0, 2, llvm::False)
842+
LoadRangeAssert(cx, ptr, 0, 2, llvm::False)
864843
} else if t.is_char() {
865844
// a char is a Unicode codepoint, and so takes values from 0
866845
// to 0x10FFFF inclusive only.
867-
LoadRangeAssert(cx, ptr.get(), 0, 0x10FFFF + 1, llvm::False)
846+
LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
868847
} else if (t.is_region_ptr() || t.is_unique())
869848
&& !common::type_is_fat_ptr(cx.tcx(), t) {
870-
LoadNonNull(cx, ptr.get())
849+
LoadNonNull(cx, ptr)
871850
} else {
872-
Load(cx, ptr.get())
851+
Load(cx, ptr)
873852
};
874853

875854
unsafe {
@@ -918,11 +897,16 @@ pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef {
918897

919898
pub fn to_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef {
920899
if ty.is_bool() {
900+
// Look for cases where we're truncating a zext from a bool already and grab the original
901+
// value. This can happen with an elided load from a boolean location. While this can be
902+
// easily optimized out, the indirection can interfere with some intrinsics.
921903
let val = Value(val);
922904
if let Some(zext) = val.as_zext_inst() {
905+
// `val` == zext %foo
923906
if let Some(val) = zext.get_operand(0) {
924907
let valty = val_ty(val.get());
925908
if valty == Type::i1(bcx.ccx()) {
909+
// %foo : i1
926910
return val.get();
927911
}
928912
}

src/librustc_trans/trans/builder.rs

+3
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
507507
}
508508

509509
pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef {
510+
debug!("Volatile Store {} -> {}",
511+
self.ccx.tn().val_to_string(val),
512+
self.ccx.tn().val_to_string(ptr));
510513
assert!(!self.llbuilder.is_null());
511514
self.count_insn("store.volatile");
512515
unsafe {

src/librustc_trans/trans/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2094,7 +2094,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
20942094
if type_is_fat_ptr(bcx.tcx(), t_in) {
20952095
if type_is_fat_ptr(bcx.tcx(), t_out) {
20962096
// If the datum is by-ref, just do a pointer cast, otherwise
2097-
// construct the casted fat pointer manually
2097+
// construct the casted fat pointer manually.
20982098
if datum.kind.is_by_ref() {
20992099
return DatumBlock::new(bcx, Datum::new(
21002100
PointerCast(bcx, datum.val, ll_t_out.ptr_to()),

src/librustc_trans/trans/value.rs

+13
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ impl Value {
8080
}
8181
}
8282

83+
pub fn get_stored_value_opt(self, bcx: Block) -> Option<Value> {
84+
let bb = Some(BasicBlock(bcx.llbb));
85+
if let Some(val) = self.get_dominating_store(bcx) {
86+
let valbb = val.get_parent();
87+
88+
if bb == valbb {
89+
return val.get_operand(0);
90+
}
91+
}
92+
93+
None
94+
}
95+
8396
/// Returns the first use of this value, if any
8497
pub fn get_first_use(self) -> Option<Use> {
8598
unsafe {

0 commit comments

Comments
 (0)