about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAustin Hicks <camlorn@camlorn.net>2016-09-24 17:37:24 -0400
committerAustin Hicks <camlorn@camlorn.net>2016-09-24 18:21:16 -0400
commit12ff05fc506335c64e6237dd14d797795c384c19 (patch)
treec81cfef4301d82d80d1dfcaf7dbade55c1241e03 /src
parent4038189688ce2705d41bec97238715aa17f44c1d (diff)
downloadrust-12ff05fc506335c64e6237dd14d797795c384c19.tar.gz
rust-12ff05fc506335c64e6237dd14d797795c384c19.zip
Clean up matches that determine integers for specific alignment requirements
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/layout.rs37
-rw-r--r--src/librustc_trans/adt.rs17
2 files changed, 31 insertions, 23 deletions
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 9bc1c1bc960..0451daf3d5f 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -339,6 +339,16 @@ impl Integer {
         }
     }
 
+    pub fn align(&self, dl: &TargetDataLayout)-> Align {
+        match *self {
+            I1 => dl.i1_align,
+            I8 => dl.i8_align,
+            I16 => dl.i16_align,
+            I32 => dl.i32_align,
+            I64 => dl.i64_align,
+        }
+    }
+
     pub fn to_ty<'a, 'tcx>(&self, tcx: &ty::TyCtxt<'a, 'tcx, 'tcx>,
                        signed: bool) -> Ty<'tcx> {
         match (*self, signed) {
@@ -377,6 +387,18 @@ impl Integer {
         }
     }
 
+    //Find the smallest integer with the given alignment.
+    pub fn for_abi_align(dl: &TargetDataLayout, align: Align) -> Option<Integer> {
+        let wanted = align.abi();
+        for &candidate in &[I8, I16, I32, I64] {
+            let ty = Int(candidate);
+            if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
+                return Some(candidate);
+            }
+        }
+        None
+    }
+
     /// Get the Integer type from an attr::IntType.
     pub fn from_attr(dl: &TargetDataLayout, ity: attr::IntType) -> Integer {
         match ity {
@@ -1149,20 +1171,7 @@ impl<'a, 'gcx, 'tcx> Layout {
                 // won't be so conservative.
 
                 // Use the initial field alignment
-                let wanted = start_align.abi();
-                let mut ity = min_ity;
-                for &candidate in &[I16, I32, I64] {
-                    let ty = Int(candidate);
-                    if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
-                        ity = candidate;
-                        break;
-                    }
-                }
-
-                // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
-                if align.abi() != start_align.abi() {
-                    ity = min_ity;
-                }
+                let mut ity = Integer::for_abi_align(dl, start_align).unwrap_or(min_ity);
 
                 // If the alignment is not larger than the chosen discriminant size,
                 // don't use the alignment as the final size.
diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs
index c7528c0cf69..c31714351dc 100644
--- a/src/librustc_trans/adt.rs
+++ b/src/librustc_trans/adt.rs
@@ -286,16 +286,15 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
 fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
     assert_eq!(size%align, 0);
+    assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align);
     let align_units = size/align;
-    match align {
-        1 => Type::array(&Type::i8(cx), align_units),
-        2 => Type::array(&Type::i16(cx), align_units),
-        4 => Type::array(&Type::i32(cx), align_units),
-        8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
-                         Type::array(&Type::i64(cx), align_units),
-        a if a.count_ones() == 1 => Type::array(&Type::vector(&Type::i32(cx), a / 4),
-                                                      align_units),
-        _ => bug!("unsupported union alignment: {}", align)
+    let dl = &cx.tcx().data_layout;
+    let layout_align = layout::Align::from_bytes(align, align).unwrap();
+    if let Some(ity) = layout::Integer::for_abi_align(dl, layout_align) {
+        Type::array(&Type::from_integer(cx, ity), align_units)
+    } else {
+        Type::array(&Type::vector(&Type::i32(cx), align/4),
+                    align_units)
     }
 }