blob: 065c760d3f38de0296e74e7ee4568b1de7ac164a [file] [log] [blame]
Sean Callanan5cf4a1c2010-07-03 01:35:46 +00001//===-- IRForTarget.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/IRForTarget.h"
11
12#include "llvm/Support/raw_ostream.h"
13#include "llvm/InstrTypes.h"
Sean Callanan8bce6652010-07-13 21:41:46 +000014#include "llvm/Instructions.h"
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000015#include "llvm/Module.h"
Sean Callanan8bce6652010-07-13 21:41:46 +000016#include "llvm/Target/TargetData.h"
17
18#include "clang/AST/ASTContext.h"
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000019
20#include "lldb/Core/dwarf.h"
21#include "lldb/Core/Log.h"
22#include "lldb/Core/Scalar.h"
23#include "lldb/Core/StreamString.h"
24#include "lldb/Expression/ClangExpressionDeclMap.h"
25
26#include <map>
27
28using namespace llvm;
29
30IRForTarget::IRForTarget(const void *pid,
Sean Callanan8bce6652010-07-13 21:41:46 +000031 lldb_private::ClangExpressionDeclMap *decl_map,
32 const llvm::TargetData *target_data) :
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000033 ModulePass(pid),
Sean Callanan8bce6652010-07-13 21:41:46 +000034 m_decl_map(decl_map),
35 m_target_data(target_data)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000036{
37}
38
39IRForTarget::~IRForTarget()
40{
41}
42
Sean Callanan8bce6652010-07-13 21:41:46 +000043static clang::NamedDecl *
44DeclForGlobalValue(llvm::Module &module,
45 llvm::GlobalValue *global_value)
46{
47 NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs");
48
49 if (!named_metadata)
50 return NULL;
51
52 unsigned num_nodes = named_metadata->getNumOperands();
53 unsigned node_index;
54
55 for (node_index = 0;
56 node_index < num_nodes;
57 ++node_index)
58 {
59 MDNode *metadata_node = named_metadata->getOperand(node_index);
60
61 if (!metadata_node)
62 return NULL;
63
64 if (metadata_node->getNumOperands() != 2)
65 return NULL;
66
67 if (metadata_node->getOperand(0) != global_value)
68 continue;
69
70 ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
71
72 if (!constant_int)
73 return NULL;
74
75 uintptr_t ptr = constant_int->getZExtValue();
76
77 return reinterpret_cast<clang::NamedDecl *>(ptr);
78 }
79
80 return NULL;
81}
82
83bool
84IRForTarget::MaybeHandleVariable(Module &M,
85 lldb_private::ClangExpressionDeclMap *DM,
86 llvm::Value *V,
87 bool Store)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000088{
Sean Callanan8bce6652010-07-13 21:41:46 +000089 if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
90 {
91 clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000092
Sean Callanan810f22d2010-07-16 00:09:46 +000093 std::string name = named_decl->getName().str();
94
95 void *qual_type = NULL;
96
97 if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
98 qual_type = value_decl->getType().getAsOpaquePtr();
99 else
100 return false;
101
Sean Callanan8bce6652010-07-13 21:41:46 +0000102 const llvm::Type *value_type = global_variable->getType();
103
104 size_t value_size = m_target_data->getTypeStoreSize(value_type);
105 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
106
Sean Callanan810f22d2010-07-16 00:09:46 +0000107 if (named_decl && !DM->AddValueToStruct(V,
108 named_decl,
109 name,
110 qual_type,
111 value_size,
112 value_alignment))
Sean Callanan8bce6652010-07-13 21:41:46 +0000113 return false;
114 }
115
116 return true;
117}
118
119bool
120IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
121{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000122 /////////////////////////////////////////////////////////////////////////
123 // Prepare the current basic block for execution in the remote process
124 //
125
Sean Callanan8bce6652010-07-13 21:41:46 +0000126 llvm::BasicBlock::iterator ii;
127
128 for (ii = BB.begin();
129 ii != BB.end();
130 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000131 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000132 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000133
Sean Callanan8bce6652010-07-13 21:41:46 +0000134 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
135 if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false))
136 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000137
Sean Callanan8bce6652010-07-13 21:41:46 +0000138 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
139 if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false))
140 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000141 }
142
143 return true;
144}
145
Sean Callananbafd6852010-07-14 23:40:29 +0000146static std::string
147PrintValue(llvm::Value *V, bool truncate = false)
Sean Callanan8bce6652010-07-13 21:41:46 +0000148{
149 std::string s;
150 raw_string_ostream rso(s);
151 V->print(rso);
152 rso.flush();
153 if (truncate)
154 s.resize(s.length() - 1);
155 return s;
156}
157
Sean Callananbafd6852010-07-14 23:40:29 +0000158// UnfoldConstant operates on a constant [C] which has just been replaced with a value
159// [new_value]. We assume that new_value has been properly placed early in the function,
160// most likely somewhere in front of the first instruction in the entry basic block
161// [first_entry_instruction].
162//
163// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
164// Where those uses are constants, the function generates new instructions to compute the
165// result of the new, non-constant expression and places them before first_entry_instruction.
166// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
167// for those.
168
169static bool
170UnfoldConstant(llvm::Constant *C, llvm::Value *new_value, llvm::Instruction *first_entry_instruction)
171{
172 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
173
174 Value::use_iterator ui;
175
176 for (ui = C->use_begin();
177 ui != C->use_end();
178 ++ui)
179 {
180 User *user = *ui;
181
182 if (Constant *constant = dyn_cast<Constant>(user))
183 {
184 // synthesize a new non-constant equivalent of the constant
185
186 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
187 {
188 switch (constant_expr->getOpcode())
189 {
190 default:
191 if (log)
192 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
193 return false;
194 case Instruction::BitCast:
195 {
196 // UnaryExpr
197 // OperandList[0] is value
198
199 Value *s = constant_expr->getOperand(0);
200
201 if (s == C)
202 s = new_value;
203
204 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
205
206 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
207 }
208 break;
209 case Instruction::GetElementPtr:
210 {
211 // GetElementPtrConstantExpr
212 // OperandList[0] is base
213 // OperandList[1]... are indices
214
215 Value *ptr = constant_expr->getOperand(0);
216
217 if (ptr == C)
218 ptr = new_value;
219
220 SmallVector<Value*, 16> indices;
221
222 unsigned operand_index;
223 unsigned num_operands = constant_expr->getNumOperands();
224
225 for (operand_index = 1;
226 operand_index < num_operands;
227 ++operand_index)
228 {
229 Value *operand = constant_expr->getOperand(operand_index);
230
231 if (operand == C)
232 operand = new_value;
233
234 indices.push_back(operand);
235 }
236
237 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
238
239 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
240 }
241 break;
242 }
243 }
244 else
245 {
246 if (log)
247 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
248 return false;
249 }
250 }
251 else
252 {
253 // simple fall-through case for non-constants
254 user->replaceUsesOfWith(C, new_value);
255 }
256 }
257
258 return true;
259}
260
Sean Callanan8bce6652010-07-13 21:41:46 +0000261bool
262IRForTarget::replaceVariables(Module &M, Function *F)
263{
264 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
265
266 m_decl_map->DoStructLayout();
267
268 if (log)
269 log->Printf("Element arrangement:");
270
271 uint32_t num_elements;
272 uint32_t element_index;
273
274 size_t size;
275 off_t alignment;
276
277 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
278 return false;
279
280 Function::arg_iterator iter(F->getArgumentList().begin());
281
282 if (iter == F->getArgumentList().end())
283 return false;
284
285 llvm::Argument *argument = iter;
286
287 if (!argument->getName().equals("___clang_arg"))
288 return false;
289
290 if (log)
291 log->Printf("Arg: %s", PrintValue(argument).c_str());
292
293 llvm::BasicBlock &entry_block(F->getEntryBlock());
294 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
295
296 if (!first_entry_instruction)
297 return false;
298
299 LLVMContext &context(M.getContext());
300 const IntegerType *offset_type(Type::getInt32Ty(context));
301
302 if (!offset_type)
303 return false;
304
305 for (element_index = 0; element_index < num_elements; ++element_index)
306 {
307 const clang::NamedDecl *decl;
308 llvm::Value *value;
309 off_t offset;
310
311 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
312 return false;
313
314 if (log)
315 log->Printf(" %s (%s) placed at %d",
316 decl->getIdentifier()->getNameStart(),
317 PrintValue(value, true).c_str(),
318 offset);
319
320 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
321 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
322 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
323
Sean Callananbafd6852010-07-14 23:40:29 +0000324 if (Constant *constant = dyn_cast<Constant>(value))
325 UnfoldConstant(constant, bit_cast, first_entry_instruction);
326 else
327 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000328 }
329
330 if (log)
331 log->Printf("Total structure [align %d, size %d]", alignment, size);
332
333 return true;
334}
335
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000336bool
337IRForTarget::runOnModule(Module &M)
338{
339 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
340
341 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
342
343 if (!function)
344 {
345 if (log)
346 log->Printf("Couldn't find ___clang_expr() in the module");
347
348 return false;
349 }
350
351 llvm::Function::iterator bbi;
352
353 for (bbi = function->begin();
354 bbi != function->end();
355 ++bbi)
356 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000357 if (!runOnBasicBlock(M, *bbi))
358 return false;
359 }
360
361 if (!replaceVariables(M, function))
362 return false;
363
364 if (log)
365 {
366 for (bbi = function->begin();
367 bbi != function->end();
368 ++bbi)
369 {
370 log->Printf("Rewrote basic block %s for running: \n%s",
371 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
372 PrintValue(bbi).c_str());
373 }
374
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000375 }
376
377 return true;
378}
379
380void
381IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000382 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000383{
384}
385
386PassManagerType
387IRForTarget::getPotentialPassManagerType() const
388{
389 return PMT_ModulePassManager;
390}