(index<- )        ./librustc/middle/trans/value.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Apr  9 17:27:02 2014
   1  // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  use lib::llvm::{llvm, UseRef, ValueRef};
  12  use middle::trans::basic_block::BasicBlock;
  13  use middle::trans::common::Block;
  14  use libc::c_uint;
  15  
  16  pub struct Value(pub ValueRef);
  17  
  18  macro_rules! opt_val ( ($e:expr) => (
  19      unsafe {
  20          match $e {
  21              p if p.is_not_null() => Some(Value(p)),
  22              _ => None
  23          }
  24      }
  25  ))
  26  
  27  /**
  28   * Wrapper for LLVM ValueRef
  29   */
  30  impl Value {
  31      /// Returns the native ValueRef
  32      pub fn get(&self) -> ValueRef {
  33          let Value(v) = *self; v
  34      }
  35  
  36      /// Returns the BasicBlock that contains this value
  37      pub fn get_parent(self) -> Option<BasicBlock> {
  38          unsafe {
  39              match llvm::LLVMGetInstructionParent(self.get()) {
  40                  p if p.is_not_null() => Some(BasicBlock(p)),
  41                  _ => None
  42              }
  43          }
  44      }
  45  
  46      /// Removes this value from its containing BasicBlock
  47      pub fn erase_from_parent(self) {
  48          unsafe {
  49              llvm::LLVMInstructionEraseFromParent(self.get());
  50          }
  51      }
  52  
  53      /// Returns the single dominating store to this value, if any
  54      /// This only performs a search for a trivially dominating store. The store
  55      /// must be the only user of this value, and there must not be any conditional
  56      /// branches between the store and the given block.
  57      pub fn get_dominating_store(self, bcx&Block) -> Option<Value> {
  58          match self.get_single_user().and_then(|user| user.as_store_inst()) {
  59              Some(store) => {
  60                  store.get_parent().and_then(|store_bb| {
  61                      let mut bb = BasicBlock(bcx.llbb);
  62                      let mut ret = Some(store);
  63                      while bb.get() != store_bb.get() {
  64                          match bb.get_single_predecessor() {
  65                              Some(pred) => bb = pred,
  66                              None => { ret = None; break }
  67                          }
  68                      }
  69                      ret
  70                  })
  71              }
  72              _ => None
  73          }
  74      }
  75  
  76      /// Returns the first use of this value, if any
  77      pub fn get_first_use(self) -> Option<Use> {
  78          unsafe {
  79              match llvm::LLVMGetFirstUse(self.get()) {
  80                  u if u.is_not_null() => Some(Use(u)),
  81                  _ => None
  82              }
  83          }
  84      }
  85  
  86      /// Tests if there are no uses of this value
  87      pub fn has_no_uses(self) -> bool {
  88          self.get_first_use().is_none()
  89      }
  90  
  91      /// Returns the single user of this value
  92      /// If there are no users or multiple users, this returns None
  93      pub fn get_single_user(self) -> Option<Value> {
  94          let mut iter = self.user_iter();
  95          match (iter.next(), iter.next()) {
  96              (Some(first), None) => Some(first),
  97              _ => None
  98          }
  99      }
 100  
 101      /// Returns an iterator for the users of this value
 102      pub fn user_iter(self) -> Users {
 103          Users {
 104              next: self.get_first_use()
 105          }
 106      }
 107  
 108      /// Returns the requested operand of this instruction
 109      /// Returns None, if there's no operand at the given index
 110      pub fn get_operand(self, iuint) -> Option<Value> {
 111          opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint))
 112      }
 113  
 114      /// Returns the Store represent by this value, if any
 115      pub fn as_store_inst(self) -> Option<Value> {
 116          opt_val!(llvm::LLVMIsAStoreInst(self.get()))
 117      }
 118  
 119      /// Tests if this value is a terminator instruction
 120      pub fn is_a_terminator_inst(self) -> bool {
 121          unsafe {
 122              llvm::LLVMIsATerminatorInst(self.get()).is_not_null()
 123          }
 124      }
 125  }
 126  
 127  pub struct Use(UseRef);
 128  
 129  /**
 130   * Wrapper for LLVM UseRef
 131   */
 132  impl Use {
 133      pub fn get(&self) -> UseRef {
 134          let Use(v) = *self; v
 135      }
 136  
 137      pub fn get_user(self) -> Value {
 138          unsafe {
 139              Value(llvm::LLVMGetUser(self.get()))
 140          }
 141      }
 142  
 143      pub fn get_next_use(self) -> Option<Use> {
 144          unsafe {
 145              match llvm::LLVMGetNextUse(self.get()) {
 146                  u if u.is_not_null() => Some(Use(u)),
 147                  _ => None
 148              }
 149          }
 150      }
 151  }
 152  
 153  /// Iterator for the users of a value
 154  pub struct Users {
 155      next: Option<Use>
 156  }
 157  
 158  impl Iterator<Value> for Users {
 159      fn next(&mut self) -> Option<Value> {
 160          let current = self.next;
 161  
 162          self.next = current.and_then(|u| u.get_next_use());
 163  
 164          current.map(|u| u.get_user())
 165      }
 166  }


librustc/middle/trans/value.rs:153:38-153:38 -struct- definition:
/// Iterator for the users of a value
pub struct Users {
    next: Option<Use>
references:- 4
101:     /// Returns an iterator for the users of this value
102:     pub fn user_iter(self) -> Users {
103:         Users {
--
158: impl Iterator<Value> for Users {
159:     fn next(&mut self) -> Option<Value> {
librustc/middle/trans/basic_block.rs:
17: pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
librustc/middle/trans/value.rs:
102:     pub fn user_iter(self) -> Users {
103:         Users {
104:             next: self.get_first_use()


librustc/middle/trans/value.rs:126:1-126:1 -struct- definition:
pub struct Use(UseRef);
/**
 * Wrapper for LLVM UseRef
references:- 4
76:     /// Returns the first use of this value, if any
77:     pub fn get_first_use(self) -> Option<Use> {
78:         unsafe {
--
143:     pub fn get_next_use(self) -> Option<Use> {
144:         unsafe {
--
154: pub struct Users {
155:     next: Option<Use>
156: }


librustc/middle/trans/value.rs:15:1-15:1 -struct- definition:
pub struct Value(pub ValueRef);
macro_rules! opt_val ( ($e:expr) => (
    unsafe {
references:- 11
56:     /// branches between the store and the given block.
57:     pub fn get_dominating_store(self, bcx: &Block) -> Option<Value> {
58:         match self.get_single_user().and_then(|user| user.as_store_inst()) {
--
92:     /// If there are no users or multiple users, this returns None
93:     pub fn get_single_user(self) -> Option<Value> {
94:         let mut iter = self.user_iter();
--
114:     /// Returns the Store represent by this value, if any
115:     pub fn as_store_inst(self) -> Option<Value> {
116:         opt_val!(llvm::LLVMIsAStoreInst(self.get()))
--
137:     pub fn get_user(self) -> Value {
138:         unsafe {
--
158: impl Iterator<Value> for Users {
159:     fn next(&mut self) -> Option<Value> {
160:         let current = self.next;
librustc/middle/trans/basic_block.rs:
27:     pub fn as_value(self) -> Value {
28:         unsafe {
librustc/middle/trans/value.rs:
109:     /// Returns None, if there's no operand at the given index
110:     pub fn get_operand(self, i: uint) -> Option<Value> {
111:         opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint))