Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
instruction-counter.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 #include <boost/foreach.hpp>
18 
19 #include "common/logging.h"
20 
21 #include "common/names.h"
22 
23 using namespace impala;
24 using namespace llvm;
25 using std::make_pair;
26 using std::max;
27 
28 const char* InstructionCounter::TOTAL_INSTS = "Total Instructions";
29 const char* InstructionCounter::TOTAL_BLOCKS = "Total Blocks";
30 const char* InstructionCounter::TOTAL_FUNCTIONS = "Total Functions";
31 const char* InstructionCounter::TERMINATOR_INSTS = "Terminator Instructions ";
32 const char* InstructionCounter::BINARY_INSTS = "Binary Instructions ";
33 const char* InstructionCounter::MEMORY_INSTS = "Memory Instructions ";
34 const char* InstructionCounter::CAST_INSTS = "Cast Instructions ";
35 const char* InstructionCounter::OTHER_INSTS = "Other Instructions ";
36 
38  // Create top level counters and put them into counters_
39  counters_.insert(make_pair(TOTAL_INSTS, 0));
40  counters_.insert(make_pair(TOTAL_BLOCKS, 0));
41  counters_.insert(make_pair(TOTAL_FUNCTIONS, 0));
42 
43  // Create all instruction counter and put them into counters_. Any InstructionCount that
44  // has instructions delegated to it in InstructionCounter::visit(const Instruction &I)
45  // must be created and inserted into counters_ here.
46  counters_.insert(make_pair(TERMINATOR_INSTS, 0));
47  counters_.insert(make_pair(BINARY_INSTS, 0));
48  counters_.insert(make_pair(MEMORY_INSTS, 0));
49  counters_.insert(make_pair(CAST_INSTS, 0));
50  counters_.insert(make_pair(OTHER_INSTS, 0));
51 }
52 
53 void InstructionCounter::visit(const Module& M) {
54  visit(M.begin(), M.end());
55 }
56 
57 void InstructionCounter::visit(const Function& F) {
58  IncrementCount(TOTAL_FUNCTIONS);
59  visit(F.begin(), F.end());
60 }
61 
62 void InstructionCounter::visit(const BasicBlock& BB) {
63  IncrementCount(TOTAL_BLOCKS);
64  visit(BB.begin(), BB.end());
65 }
66 
68  CounterMap::const_iterator counter = counters_.find(name);
69  DCHECK(counter != counters_.end());
70  return counter->second;
71 }
72 
73 void InstructionCounter::visit(const Instruction& I) {
74  IncrementCount(TOTAL_INSTS);
75  switch (I.getOpcode()) {
76  case llvm::Instruction::Ret:
77  case llvm::Instruction::Br:
78  case llvm::Instruction::Switch:
79  case llvm::Instruction::IndirectBr:
80  case llvm::Instruction::Invoke:
81  case llvm::Instruction::Resume:
82  case llvm::Instruction::Unreachable:
83  IncrementCount(TERMINATOR_INSTS);
84  break;
85  case llvm::Instruction::Add:
86  case llvm::Instruction::FAdd:
87  case llvm::Instruction::Sub:
88  case llvm::Instruction::FSub:
89  case llvm::Instruction::Mul:
90  case llvm::Instruction::FMul:
91  case llvm::Instruction::UDiv:
92  case llvm::Instruction::SDiv:
93  case llvm::Instruction::FDiv:
94  case llvm::Instruction::URem:
95  case llvm::Instruction::SRem:
96  case llvm::Instruction::FRem:
97  case llvm::Instruction::Shl:
98  case llvm::Instruction::LShr:
99  case llvm::Instruction::AShr:
100  case llvm::Instruction::And:
101  case llvm::Instruction::Or:
102  case llvm::Instruction::Xor:
103  IncrementCount(BINARY_INSTS);
104  break;
105  case llvm::Instruction::Alloca:
106  case llvm::Instruction::Load:
107  case llvm::Instruction::Store:
108  case llvm::Instruction::Fence:
109  case llvm::Instruction::AtomicCmpXchg:
110  case llvm::Instruction::AtomicRMW:
111  IncrementCount(MEMORY_INSTS);
112  break;
113  case llvm::Instruction::Trunc:
114  case llvm::Instruction::ZExt:
115  case llvm::Instruction::SExt:
116  case llvm::Instruction::FPToUI:
117  case llvm::Instruction::FPToSI:
118  case llvm::Instruction::UIToFP:
119  case llvm::Instruction::SIToFP:
120  case llvm::Instruction::FPTrunc:
121  case llvm::Instruction::FPExt:
122  case llvm::Instruction::PtrToInt:
123  case llvm::Instruction::IntToPtr:
124  case llvm::Instruction::BitCast:
125  IncrementCount(CAST_INSTS);
126  break;
127  case llvm::Instruction::ICmp:
128  case llvm::Instruction::FCmp:
129  case llvm::Instruction::PHI:
130  case llvm::Instruction::Call:
131  case llvm::Instruction::Select:
132  case llvm::Instruction::UserOp1:
133  case llvm::Instruction::UserOp2:
134  case llvm::Instruction::VAArg:
135  case llvm::Instruction::ExtractElement:
136  case llvm::Instruction::InsertElement:
137  case llvm::Instruction::ShuffleVector:
138  case llvm::Instruction::ExtractValue:
139  case llvm::Instruction::InsertValue:
140  case llvm::Instruction::LandingPad:
141  case llvm::Instruction::GetElementPtr:
142  IncrementCount(OTHER_INSTS);
143  break;
144  default:
145  DCHECK(false);
146  }
147 }
148 
150  BOOST_FOREACH(CounterMap::value_type& counter, counters_) {
151  counter.second = 0;
152  }
153 }
154 
155 void InstructionCounter::PrintCounter(const char* name, int count, int max_count_len,
156  stringstream* stream) const {
157  if (count > 0) {
158  *stream << left << setw(max_count_len + 1) << setfill(' ') << count << setw(35)
159  << setfill(' ') << name << left << setw(10 - max_count_len) << setfill(' ')
160  << "Number of " << name << endl;
161  }
162 }
163 
165  // Find the longest length of all the InstructionCount count_ strings.
166  int max_count_len = 0;
167  stringstream count_stream;
168  BOOST_FOREACH(const CounterMap::value_type& counter, counters_) {
169  count_stream << counter.second;
170  max_count_len =
171  max(max_count_len, static_cast<int>(strlen(count_stream.str().c_str())));
172  count_stream.str("");
173  }
174  stringstream stream;
175  // Print header
176  stream << "\n===" << string(73, '-') << "===\n\n"
177  << " ... Instruction Counts ...\n\n"
178  << "===" << string(73, '-') << "===\n\n";
179 
180  BOOST_FOREACH(const CounterMap::value_type& counter, counters_) {
181  // Conditional is only used in order to print the top level counters
182  // separate from the other counters.
183  if (strcmp(counter.first.c_str(), TOTAL_BLOCKS) == 0) {
184  stream << "\n===" << string(73, '-') << "===\n"
185  << " ... Totals ...\n"
186  << "===" << string(73, '-') << "===\n\n";
187  }
188  PrintCounter(counter.first.c_str(), counter.second, max_count_len, &stream);
189  }
190  stream << '\n';
191  return stream.str();
192 }
193 
195  CounterMap::iterator iter = counters_.find(name);
196  DCHECK(iter != counters_.end());
197  iter->second++;
198 }
static const char * TOTAL_INSTS
String constants for instruction count names.
int GetCount(const char *name)
Return count of counter described by name.
void ResetCount()
Set all counts to 0.
static const char * OTHER_INSTS
static const char * CAST_INSTS
static const char * TOTAL_BLOCKS
void PrintCounter(const char *name, int count, int max_count_len, std::stringstream *stream) const
Prints a single counter described by name and count.
static const char * TERMINATOR_INSTS
std::string PrintCounters() const
Prints all counters.
uint64_t count
void visit(const llvm::Module &M)
Visits each Function in Module M.
static const char * TOTAL_FUNCTIONS
string name
Definition: cpu-info.cc:50
static const char * BINARY_INSTS
void IncrementCount(const char *name)
Increment InstructionCount with name_ equal to name argument.
static const char * MEMORY_INSTS