-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'remotes/origin/master' into cleanup-ite…
…rators
- Loading branch information
Showing
8 changed files
with
268 additions
and
17 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use lib::llvm::{llvm, BasicBlockRef}; | ||
use middle::trans::value::{UserIterator, Value}; | ||
use std::iterator::{Filter, Map}; | ||
|
||
pub struct BasicBlock(BasicBlockRef); | ||
|
||
pub type PredIterator<'self> = Map<'self, Value, BasicBlock, Filter<'self, Value, UserIterator>>; | ||
|
||
/** | ||
* Wrapper for LLVM BasicBlockRef | ||
*/ | ||
impl BasicBlock { | ||
pub fn as_value(self) -> Value { | ||
unsafe { | ||
Value(llvm::LLVMBasicBlockAsValue(*self)) | ||
} | ||
} | ||
|
||
pub fn pred_iter(self) -> PredIterator { | ||
self.as_value().user_iter() | ||
.filter(|user| user.is_a_terminator_inst()) | ||
.map(|user| user.get_parent().unwrap()) | ||
} | ||
|
||
pub fn get_single_predecessor(self) -> Option<BasicBlock> { | ||
let mut iter = self.pred_iter(); | ||
match (iter.next(), iter.next()) { | ||
(Some(first), None) => Some(first), | ||
_ => None | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,5 @@ pub mod machine; | |
pub mod adt; | ||
pub mod asm; | ||
pub mod type_; | ||
pub mod value; | ||
pub mod basic_block; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use lib::llvm::{llvm, UseRef, ValueRef}; | ||
use middle::trans::basic_block::BasicBlock; | ||
use middle::trans::common::Block; | ||
use std::libc::c_uint; | ||
|
||
pub struct Value(ValueRef); | ||
|
||
macro_rules! opt_val ( ($e:expr) => ( | ||
unsafe { | ||
match $e { | ||
p if p.is_not_null() => Some(Value(p)), | ||
_ => None | ||
} | ||
} | ||
)) | ||
|
||
/** | ||
* Wrapper for LLVM ValueRef | ||
*/ | ||
impl Value { | ||
/// Returns the BasicBlock that contains this value | ||
pub fn get_parent(self) -> Option<BasicBlock> { | ||
unsafe { | ||
match llvm::LLVMGetInstructionParent(*self) { | ||
p if p.is_not_null() => Some(BasicBlock(p)), | ||
_ => None | ||
} | ||
} | ||
} | ||
|
||
/// Removes this value from its containing BasicBlock | ||
pub fn erase_from_parent(self) { | ||
unsafe { | ||
llvm::LLVMInstructionEraseFromParent(*self); | ||
} | ||
} | ||
|
||
/// Returns the single dominating store to this value, if any | ||
/// This only performs a search for a trivially dominating store. The store | ||
/// must be the only user of this value, and there must not be any conditional | ||
/// branches between the store and the given block. | ||
pub fn get_dominating_store(self, bcx: @mut Block) -> Option<Value> { | ||
match self.get_single_user().chain(|user| user.as_store_inst()) { | ||
Some(store) => { | ||
do store.get_parent().chain |store_bb| { | ||
let mut bb = BasicBlock(bcx.llbb); | ||
let mut ret = Some(store); | ||
while *bb != *store_bb { | ||
match bb.get_single_predecessor() { | ||
Some(pred) => bb = pred, | ||
None => { ret = None; break } | ||
} | ||
} | ||
ret | ||
} | ||
} | ||
_ => None | ||
} | ||
} | ||
|
||
/// Returns the first use of this value, if any | ||
pub fn get_first_use(self) -> Option<Use> { | ||
unsafe { | ||
match llvm::LLVMGetFirstUse(*self) { | ||
u if u.is_not_null() => Some(Use(u)), | ||
_ => None | ||
} | ||
} | ||
} | ||
|
||
/// Tests if there are no uses of this value | ||
pub fn has_no_uses(self) -> bool { | ||
self.get_first_use().is_none() | ||
} | ||
|
||
/// Returns the single user of this value | ||
/// If there are no users or multiple users, this returns None | ||
pub fn get_single_user(self) -> Option<Value> { | ||
let mut iter = self.user_iter(); | ||
match (iter.next(), iter.next()) { | ||
(Some(first), None) => Some(first), | ||
_ => None | ||
} | ||
} | ||
|
||
/// Returns an iterator for the users of this value | ||
pub fn user_iter(self) -> UserIterator { | ||
UserIterator { | ||
next: self.get_first_use() | ||
} | ||
} | ||
|
||
/// Returns the requested operand of this instruction | ||
/// Returns None, if there's no operand at the given index | ||
pub fn get_operand(self, i: uint) -> Option<Value> { | ||
opt_val!(llvm::LLVMGetOperand(*self, i as c_uint)) | ||
} | ||
|
||
/// Returns the Store represent by this value, if any | ||
pub fn as_store_inst(self) -> Option<Value> { | ||
opt_val!(llvm::LLVMIsAStoreInst(*self)) | ||
} | ||
|
||
/// Tests if this value is a terminator instruction | ||
pub fn is_a_terminator_inst(self) -> bool { | ||
unsafe { | ||
llvm::LLVMIsATerminatorInst(*self).is_not_null() | ||
} | ||
} | ||
} | ||
|
||
pub struct Use(UseRef); | ||
|
||
/** | ||
* Wrapper for LLVM UseRef | ||
*/ | ||
impl Use { | ||
pub fn get_user(self) -> Value { | ||
unsafe { | ||
Value(llvm::LLVMGetUser(*self)) | ||
} | ||
} | ||
|
||
pub fn get_next_use(self) -> Option<Use> { | ||
unsafe { | ||
match llvm::LLVMGetNextUse(*self) { | ||
u if u.is_not_null() => Some(Use(u)), | ||
_ => None | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Iterator for the users of a value | ||
pub struct UserIterator { | ||
priv next: Option<Use> | ||
} | ||
|
||
impl Iterator<Value> for UserIterator { | ||
fn next(&mut self) -> Option<Value> { | ||
let current = self.next; | ||
|
||
self.next = do current.chain |u| { u.get_next_use() }; | ||
|
||
do current.map |u| { u.get_user() } | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern "C" | ||
int test() { | ||
return 5; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#[no_mangle] | ||
fn test() -> int { | ||
5 | ||
} |
c8a93ef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saw approval from erickt
at erickt@c8a93ef
c8a93ef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merging erickt/rust/cleanup-iterators = c8a93ef into auto
c8a93ef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
erickt/rust/cleanup-iterators = c8a93ef merged ok, testing candidate = 8b9e1ce
c8a93ef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all tests pass:
success: http://buildbot.rust-lang.org/builders/auto-mac-32-opt/builds/860
success: http://buildbot.rust-lang.org/builders/auto-mac-64-opt/builds/863
success: http://buildbot.rust-lang.org/builders/auto-mac-64-nopt/builds/864
success: http://buildbot.rust-lang.org/builders/auto-mac-all-opt/builds/860
success: http://buildbot.rust-lang.org/builders/auto-linux-32-opt/builds/878
success: http://buildbot.rust-lang.org/builders/auto-linux-32-nopt/builds/880
success: http://buildbot.rust-lang.org/builders/auto-linux-64-opt/builds/878
success: http://buildbot.rust-lang.org/builders/auto-linux-64-nopt/builds/882
success: http://buildbot.rust-lang.org/builders/auto-linux-64-opt-vg/builds/887
success: http://buildbot.rust-lang.org/builders/auto-linux-64-x-android/builds/51
success: http://buildbot.rust-lang.org/builders/auto-linux-all-opt/builds/880
success: http://buildbot.rust-lang.org/builders/auto-win-32-opt/builds/863
success: http://buildbot.rust-lang.org/builders/auto-win-32-nopt/builds/877
success: http://buildbot.rust-lang.org/builders/auto-bsd-64-opt/builds/650
c8a93ef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fast-forwarding master to auto = 8b9e1ce