2013-07-28 09:40:35 -05:00
|
|
|
// 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.
|
|
|
|
|
2014-07-07 19:58:01 -05:00
|
|
|
use llvm;
|
|
|
|
use llvm::{UseRef, ValueRef};
|
2014-11-15 19:30:33 -06:00
|
|
|
use trans::basic_block::BasicBlock;
|
|
|
|
use trans::common::Block;
|
2014-02-26 11:58:41 -06:00
|
|
|
use libc::c_uint;
|
2013-07-28 09:40:35 -05:00
|
|
|
|
2015-03-30 08:38:44 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2014-03-31 21:01:01 -05:00
|
|
|
pub struct Value(pub ValueRef);
|
2013-07-28 09:40:35 -05:00
|
|
|
|
2014-11-14 11:18:10 -06:00
|
|
|
macro_rules! opt_val { ($e:expr) => (
|
2013-07-28 09:40:35 -05:00
|
|
|
unsafe {
|
|
|
|
match $e {
|
2014-12-19 10:57:12 -06:00
|
|
|
p if !p.is_null() => Some(Value(p)),
|
2013-07-28 09:40:35 -05:00
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
2014-11-14 11:18:10 -06:00
|
|
|
) }
|
2013-07-28 09:40:35 -05:00
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Wrapper for LLVM ValueRef
|
2013-07-28 09:40:35 -05:00
|
|
|
impl Value {
|
2013-11-01 20:06:31 -05:00
|
|
|
/// Returns the native ValueRef
|
|
|
|
pub fn get(&self) -> ValueRef {
|
|
|
|
let Value(v) = *self; v
|
|
|
|
}
|
|
|
|
|
2013-07-28 09:40:35 -05:00
|
|
|
/// Returns the BasicBlock that contains this value
|
|
|
|
pub fn get_parent(self) -> Option<BasicBlock> {
|
|
|
|
unsafe {
|
2013-11-01 20:06:31 -05:00
|
|
|
match llvm::LLVMGetInstructionParent(self.get()) {
|
2014-12-19 10:57:12 -06:00
|
|
|
p if !p.is_null() => Some(BasicBlock(p)),
|
2013-07-28 09:40:35 -05:00
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Removes this value from its containing BasicBlock
|
|
|
|
pub fn erase_from_parent(self) {
|
|
|
|
unsafe {
|
2013-11-01 20:06:31 -05:00
|
|
|
llvm::LLVMInstructionEraseFromParent(self.get());
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2014-09-06 11:13:04 -05:00
|
|
|
pub fn get_dominating_store(self, bcx: Block) -> Option<Value> {
|
2013-09-11 14:52:17 -05:00
|
|
|
match self.get_single_user().and_then(|user| user.as_store_inst()) {
|
2013-07-28 09:40:35 -05:00
|
|
|
Some(store) => {
|
2013-11-21 17:42:55 -06:00
|
|
|
store.get_parent().and_then(|store_bb| {
|
2013-07-28 09:40:35 -05:00
|
|
|
let mut bb = BasicBlock(bcx.llbb);
|
|
|
|
let mut ret = Some(store);
|
2013-11-01 20:06:31 -05:00
|
|
|
while bb.get() != store_bb.get() {
|
2013-07-28 09:40:35 -05:00
|
|
|
match bb.get_single_predecessor() {
|
|
|
|
Some(pred) => bb = pred,
|
|
|
|
None => { ret = None; break }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret
|
2013-11-21 17:42:55 -06:00
|
|
|
})
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the first use of this value, if any
|
|
|
|
pub fn get_first_use(self) -> Option<Use> {
|
|
|
|
unsafe {
|
2013-11-01 20:06:31 -05:00
|
|
|
match llvm::LLVMGetFirstUse(self.get()) {
|
2014-12-19 10:57:12 -06:00
|
|
|
u if !u.is_null() => Some(Use(u)),
|
2013-07-28 09:40:35 -05:00
|
|
|
_ => 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
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn user_iter(self) -> Users {
|
|
|
|
Users {
|
2013-07-28 09:40:35 -05:00
|
|
|
next: self.get_first_use()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the requested operand of this instruction
|
|
|
|
/// Returns None, if there's no operand at the given index
|
2015-03-25 19:06:52 -05:00
|
|
|
pub fn get_operand(self, i: usize) -> Option<Value> {
|
2013-11-01 20:06:31 -05:00
|
|
|
opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint))
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the Store represent by this value, if any
|
|
|
|
pub fn as_store_inst(self) -> Option<Value> {
|
2013-11-01 20:06:31 -05:00
|
|
|
opt_val!(llvm::LLVMIsAStoreInst(self.get()))
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Tests if this value is a terminator instruction
|
|
|
|
pub fn is_a_terminator_inst(self) -> bool {
|
|
|
|
unsafe {
|
2014-12-19 10:57:12 -06:00
|
|
|
!llvm::LLVMIsATerminatorInst(self.get()).is_null()
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 19:01:33 -06:00
|
|
|
/// Wrapper for LLVM UseRef
|
2015-03-30 08:38:44 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2013-07-28 09:40:35 -05:00
|
|
|
pub struct Use(UseRef);
|
|
|
|
|
|
|
|
impl Use {
|
2013-11-01 20:06:31 -05:00
|
|
|
pub fn get(&self) -> UseRef {
|
|
|
|
let Use(v) = *self; v
|
|
|
|
}
|
|
|
|
|
2013-07-28 09:40:35 -05:00
|
|
|
pub fn get_user(self) -> Value {
|
|
|
|
unsafe {
|
2013-11-01 20:06:31 -05:00
|
|
|
Value(llvm::LLVMGetUser(self.get()))
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_next_use(self) -> Option<Use> {
|
|
|
|
unsafe {
|
2013-11-01 20:06:31 -05:00
|
|
|
match llvm::LLVMGetNextUse(self.get()) {
|
2014-12-19 10:57:12 -06:00
|
|
|
u if !u.is_null() => Some(Use(u)),
|
2013-07-28 09:40:35 -05:00
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Iterator for the users of a value
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct Users {
|
2014-03-28 12:05:27 -05:00
|
|
|
next: Option<Use>
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
|
2015-01-01 22:54:03 -06:00
|
|
|
impl Iterator for Users {
|
|
|
|
type Item = Value;
|
|
|
|
|
2013-07-28 09:40:35 -05:00
|
|
|
fn next(&mut self) -> Option<Value> {
|
|
|
|
let current = self.next;
|
|
|
|
|
2013-11-21 17:42:55 -06:00
|
|
|
self.next = current.and_then(|u| u.get_next_use());
|
2013-07-28 09:40:35 -05:00
|
|
|
|
2013-11-21 17:42:55 -06:00
|
|
|
current.map(|u| u.get_user())
|
2013-07-28 09:40:35 -05:00
|
|
|
}
|
|
|
|
}
|