Created
October 22, 2016 17:15
-
-
Save bluss/f4a203aa86fbb041e4f6ee61b712bee1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'chain_more_codegen.cgu-0.rs' | |
source_filename = "chain_more_codegen.cgu-0.rs" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
%"8.unwind::libunwind::_Unwind_Exception" = type { i64, void (i32, %"8.unwind::libunwind::_Unwind_Exception"*)*, [6 x i64] } | |
%"8.unwind::libunwind::_Unwind_Context" = type {} | |
; Function Attrs: uwtable | |
define i64 @range_chain_default_fold(i64, i64, i64 (i64, i64)* nocapture) unnamed_addr #0 personality i32 (i32, i32, i64, %"8.unwind::libunwind::_Unwind_Exception"*, %"8.unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality { | |
entry-block: | |
br label %bb6.i | |
bb6.i: ; preds = %bb11.i, %entry-block | |
%iter.sroa.9.0.i = phi i64 [ 0, %entry-block ], [ %iter.sroa.9.3.ph.i, %bb11.i ] | |
%iter.sroa.15.0.i = phi i8 [ 0, %entry-block ], [ %iter.sroa.15.1.ph.i, %bb11.i ] | |
%iter.sroa.0.0.i = phi i64 [ 0, %entry-block ], [ %iter.sroa.0.2.ph.i, %bb11.i ] | |
%accum.0.i = phi i64 [ 0, %entry-block ], [ %11, %bb11.i ] | |
%trunc.i.i = trunc i8 %iter.sroa.15.0.i to i2 | |
switch i2 %trunc.i.i, label %unreachable.i.i [ | |
i2 0, label %bb1.i.i | |
i2 1, label %bb2.i.i | |
i2 -2, label %bb3.i.i | |
] | |
bb1.i.i: ; preds = %bb6.i | |
%3 = icmp ult i64 %iter.sroa.0.0.i, %0 | |
br i1 %3, label %bb9.i.i, label %bb8.i.i | |
bb2.i.i: ; preds = %bb6.i | |
%4 = icmp ult i64 %iter.sroa.0.0.i, %0 | |
br i1 %4, label %bb2.i21.i.i, label %_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E.exit | |
bb2.i21.i.i: ; preds = %bb2.i.i | |
%5 = add i64 %iter.sroa.0.0.i, 1 | |
br label %bb11.i | |
bb3.i.i: ; preds = %bb6.i | |
%6 = icmp ult i64 %iter.sroa.9.0.i, %1 | |
br i1 %6, label %bb2.i16.i.i, label %_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E.exit | |
bb2.i16.i.i: ; preds = %bb3.i.i | |
%7 = add i64 %iter.sroa.9.0.i, 1 | |
br label %bb11.i | |
bb8.i.i: ; preds = %bb1.i.i | |
%8 = icmp ult i64 %iter.sroa.9.0.i, %1 | |
br i1 %8, label %bb2.i11.i.i, label %_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E.exit | |
bb2.i11.i.i: ; preds = %bb8.i.i | |
%9 = add i64 %iter.sroa.9.0.i, 1 | |
br label %bb11.i | |
bb9.i.i: ; preds = %bb1.i.i | |
%10 = add i64 %iter.sroa.0.0.i, 1 | |
br label %bb11.i | |
unreachable.i.i: ; preds = %bb6.i | |
unreachable | |
bb11.i: ; preds = %bb9.i.i, %bb2.i11.i.i, %bb2.i16.i.i, %bb2.i21.i.i | |
%iter.sroa.9.3.ph.i = phi i64 [ %9, %bb2.i11.i.i ], [ %7, %bb2.i16.i.i ], [ %iter.sroa.9.0.i, %bb2.i21.i.i ], [ %iter.sroa.9.0.i, %bb9.i.i ] | |
%iter.sroa.15.1.ph.i = phi i8 [ 2, %bb2.i11.i.i ], [ %iter.sroa.15.0.i, %bb2.i16.i.i ], [ %iter.sroa.15.0.i, %bb2.i21.i.i ], [ %iter.sroa.15.0.i, %bb9.i.i ] | |
%iter.sroa.0.2.ph.i = phi i64 [ %iter.sroa.0.0.i, %bb2.i11.i.i ], [ %iter.sroa.0.0.i, %bb2.i16.i.i ], [ %5, %bb2.i21.i.i ], [ %10, %bb9.i.i ] | |
%_15.sroa.8.4.ph.i = phi i64 [ %iter.sroa.9.0.i, %bb2.i11.i.i ], [ %iter.sroa.9.0.i, %bb2.i16.i.i ], [ %iter.sroa.0.0.i, %bb2.i21.i.i ], [ %iter.sroa.0.0.i, %bb9.i.i ] | |
%11 = tail call i64 %2(i64 %accum.0.i, i64 %_15.sroa.8.4.ph.i), !noalias !0 | |
br label %bb6.i | |
_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E.exit: ; preds = %bb2.i.i, %bb3.i.i, %bb8.i.i | |
ret i64 %accum.0.i | |
} | |
; Function Attrs: uwtable | |
define i64 @range_chain_custom_fold(i64, i64, i64 (i64, i64)* nocapture) unnamed_addr #0 personality i32 (i32, i32, i64, %"8.unwind::libunwind::_Unwind_Exception"*, %"8.unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality { | |
bb5.i: | |
%3 = icmp eq i64 %0, 0 | |
br i1 %3, label %bb8.i, label %bb11.i.i.preheader | |
bb11.i.i.preheader: ; preds = %bb5.i | |
br label %bb11.i.i | |
bb11.i.i: ; preds = %bb11.i.i.preheader, %bb11.i.i | |
%accum.012.i.i = phi i64 [ %5, %bb11.i.i ], [ 0, %bb11.i.i.preheader ] | |
%iter.sroa.0.011.i.i = phi i64 [ %4, %bb11.i.i ], [ 0, %bb11.i.i.preheader ] | |
%4 = add nuw i64 %iter.sroa.0.011.i.i, 1 | |
%5 = tail call i64 %2(i64 %accum.012.i.i, i64 %iter.sroa.0.011.i.i), !noalias !3 | |
%exitcond.i.i = icmp eq i64 %4, %0 | |
br i1 %exitcond.i.i, label %bb8.i.loopexit, label %bb11.i.i | |
bb8.i.loopexit: ; preds = %bb11.i.i | |
br label %bb8.i | |
bb8.i: ; preds = %bb8.i.loopexit, %bb5.i | |
%accum.0.i = phi i64 [ 0, %bb5.i ], [ %5, %bb8.i.loopexit ] | |
%6 = icmp eq i64 %1, 0 | |
br i1 %6, label %_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit, label %bb11.i7.i.preheader | |
bb11.i7.i.preheader: ; preds = %bb8.i | |
br label %bb11.i7.i | |
bb11.i7.i: ; preds = %bb11.i7.i.preheader, %bb11.i7.i | |
%accum.012.i3.i = phi i64 [ %8, %bb11.i7.i ], [ %accum.0.i, %bb11.i7.i.preheader ] | |
%iter.sroa.0.011.i4.i = phi i64 [ %7, %bb11.i7.i ], [ 0, %bb11.i7.i.preheader ] | |
%7 = add nuw i64 %iter.sroa.0.011.i4.i, 1 | |
%8 = tail call i64 %2(i64 %accum.012.i3.i, i64 %iter.sroa.0.011.i4.i), !noalias !3 | |
%exitcond.i6.i = icmp eq i64 %7, %1 | |
br i1 %exitcond.i6.i, label %_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit.loopexit, label %bb11.i7.i | |
_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit.loopexit: ; preds = %bb11.i7.i | |
br label %_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit | |
_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit: ; preds = %_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit.loopexit, %bb8.i | |
%accum.1.i = phi i64 [ %accum.0.i, %bb8.i ], [ %8, %_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E.exit.loopexit ] | |
ret i64 %accum.1.i | |
} | |
; Function Attrs: nounwind | |
declare i32 @rust_eh_personality(i32, i32, i64, %"8.unwind::libunwind::_Unwind_Exception"*, %"8.unwind::libunwind::_Unwind_Context"*) unnamed_addr #1 | |
attributes #0 = { uwtable } | |
attributes #1 = { nounwind } | |
!0 = !{!1} | |
!1 = distinct !{!1, !2, !"_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E: argument 0"} | |
!2 = distinct !{!2, !"_ZN4core4iter8iterator8Iterator4fold17h2dd9e388c2016361E"} | |
!3 = !{!4} | |
!4 = distinct !{!4, !5, !"_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E: argument 0"} | |
!5 = distinct !{!5, !"_ZN18chain_more_codegen4fold17h9ac2aaed4568fdf9E"} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![crate_type="lib"] | |
#[no_mangle] | |
pub fn range_chain_default_fold(xs: usize, ys: usize, f: fn(usize, usize) -> usize) -> usize { | |
chain(0..xs, 0..ys).fold(0, f) | |
} | |
#[no_mangle] | |
pub fn range_chain_custom_fold(xs: usize, ys: usize, f: fn(usize, usize) -> usize) -> usize { | |
fold(chain(0..xs, 0..ys), 0, f) | |
} | |
pub struct Chain<A, B> { | |
a: A, | |
b: B, | |
state: ChainState, | |
} | |
fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter> | |
where A: IntoIterator, B: IntoIterator<Item=A::Item>, | |
{ | |
Chain { | |
a: a.into_iter(), | |
b: b.into_iter(), | |
state: ChainState::Both, | |
} | |
} | |
// The iterator protocol specifies that iteration ends with the return value | |
// `None` from `.next()` (or `.next_back()`) and it is unspecified what | |
// further calls return. The chain adaptor must account for this since it uses | |
// two subiterators. | |
// | |
// It uses three states: | |
// | |
// - Both: `a` and `b` are remaining | |
// - Front: `a` remaining | |
// - Back: `b` remaining | |
// | |
// The fourth state (neither iterator is remaining) only occurs after Chain has | |
// returned None once, so we don't need to store this state. | |
enum ChainState { | |
// both front and back iterator are remaining | |
Both, | |
// only front is remaining | |
Front, | |
// only back is remaining | |
Back, | |
} | |
impl<A, B> Iterator for Chain<A, B> where | |
A: Iterator, | |
B: Iterator<Item = A::Item> | |
{ | |
type Item = A::Item; | |
#[inline] | |
fn next(&mut self) -> Option<A::Item> { | |
match self.state { | |
ChainState::Both => match self.a.next() { | |
elt @ Some(..) => elt, | |
None => { | |
self.state = ChainState::Back; | |
self.b.next() | |
} | |
}, | |
ChainState::Front => self.a.next(), | |
ChainState::Back => self.b.next(), | |
} | |
} | |
} | |
fn fold<A, B, Acc, F>(self_: Chain<A, B>, init: Acc, mut f: F) -> Acc | |
where F: FnMut(Acc, A::Item) -> Acc, | |
A: Iterator, | |
B: Iterator<Item=A::Item>, | |
{ | |
let mut accum = init; | |
match self_.state { | |
ChainState::Both | ChainState::Front => { | |
accum = self_.a.fold(accum, &mut f); | |
} | |
_ => { } | |
} | |
match self_.state { | |
ChainState::Both | ChainState::Back => { | |
accum = self_.b.fold(accum, &mut f); | |
} | |
_ => { } | |
} | |
accum | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment