blob: 31f3343d82e65336f7d4f0301ec0bf05af820a90 [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;
Sean Callananf328c9f2010-07-20 23:31:16 +000096 clang::ASTContext *ast_context = NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +000097
98 if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
Sean Callananf328c9f2010-07-20 23:31:16 +000099 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000100 qual_type = value_decl->getType().getAsOpaquePtr();
Sean Callananf328c9f2010-07-20 23:31:16 +0000101 ast_context = &value_decl->getASTContext();
102 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000103 else
Sean Callananf328c9f2010-07-20 23:31:16 +0000104 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000105 return false;
Sean Callananf328c9f2010-07-20 23:31:16 +0000106 }
107
Sean Callanan8bce6652010-07-13 21:41:46 +0000108 const llvm::Type *value_type = global_variable->getType();
109
110 size_t value_size = m_target_data->getTypeStoreSize(value_type);
111 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
112
Sean Callanan810f22d2010-07-16 00:09:46 +0000113 if (named_decl && !DM->AddValueToStruct(V,
114 named_decl,
115 name,
116 qual_type,
Sean Callananf328c9f2010-07-20 23:31:16 +0000117 ast_context,
Sean Callanan810f22d2010-07-16 00:09:46 +0000118 value_size,
119 value_alignment))
Sean Callanan8bce6652010-07-13 21:41:46 +0000120 return false;
121 }
122
123 return true;
124}
125
126bool
127IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
128{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000129 /////////////////////////////////////////////////////////////////////////
130 // Prepare the current basic block for execution in the remote process
131 //
132
Sean Callanan8bce6652010-07-13 21:41:46 +0000133 llvm::BasicBlock::iterator ii;
134
135 for (ii = BB.begin();
136 ii != BB.end();
137 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000138 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000139 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000140
Sean Callanan8bce6652010-07-13 21:41:46 +0000141 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
142 if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false))
143 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000144
Sean Callanan8bce6652010-07-13 21:41:46 +0000145 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
146 if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false))
147 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000148 }
149
150 return true;
151}
152
Sean Callananbafd6852010-07-14 23:40:29 +0000153static std::string
154PrintValue(llvm::Value *V, bool truncate = false)
Sean Callanan8bce6652010-07-13 21:41:46 +0000155{
156 std::string s;
157 raw_string_ostream rso(s);
158 V->print(rso);
159 rso.flush();
160 if (truncate)
161 s.resize(s.length() - 1);
162 return s;
163}
164
Sean Callananbafd6852010-07-14 23:40:29 +0000165// UnfoldConstant operates on a constant [C] which has just been replaced with a value
166// [new_value]. We assume that new_value has been properly placed early in the function,
167// most likely somewhere in front of the first instruction in the entry basic block
168// [first_entry_instruction].
169//
170// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
171// Where those uses are constants, the function generates new instructions to compute the
172// result of the new, non-constant expression and places them before first_entry_instruction.
173// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
174// for those.
175
176static bool
177UnfoldConstant(llvm::Constant *C, llvm::Value *new_value, llvm::Instruction *first_entry_instruction)
178{
179 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
180
181 Value::use_iterator ui;
182
183 for (ui = C->use_begin();
184 ui != C->use_end();
185 ++ui)
186 {
187 User *user = *ui;
188
189 if (Constant *constant = dyn_cast<Constant>(user))
190 {
191 // synthesize a new non-constant equivalent of the constant
192
193 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
194 {
195 switch (constant_expr->getOpcode())
196 {
197 default:
198 if (log)
199 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
200 return false;
201 case Instruction::BitCast:
202 {
203 // UnaryExpr
204 // OperandList[0] is value
205
206 Value *s = constant_expr->getOperand(0);
207
208 if (s == C)
209 s = new_value;
210
211 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
212
213 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
214 }
215 break;
216 case Instruction::GetElementPtr:
217 {
218 // GetElementPtrConstantExpr
219 // OperandList[0] is base
220 // OperandList[1]... are indices
221
222 Value *ptr = constant_expr->getOperand(0);
223
224 if (ptr == C)
225 ptr = new_value;
226
227 SmallVector<Value*, 16> indices;
228
229 unsigned operand_index;
230 unsigned num_operands = constant_expr->getNumOperands();
231
232 for (operand_index = 1;
233 operand_index < num_operands;
234 ++operand_index)
235 {
236 Value *operand = constant_expr->getOperand(operand_index);
237
238 if (operand == C)
239 operand = new_value;
240
241 indices.push_back(operand);
242 }
243
244 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
245
246 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
247 }
248 break;
249 }
250 }
251 else
252 {
253 if (log)
254 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
255 return false;
256 }
257 }
258 else
259 {
260 // simple fall-through case for non-constants
261 user->replaceUsesOfWith(C, new_value);
262 }
263 }
264
265 return true;
266}
267
Sean Callanan8bce6652010-07-13 21:41:46 +0000268bool
269IRForTarget::replaceVariables(Module &M, Function *F)
270{
271 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
272
273 m_decl_map->DoStructLayout();
274
275 if (log)
276 log->Printf("Element arrangement:");
277
278 uint32_t num_elements;
279 uint32_t element_index;
280
281 size_t size;
282 off_t alignment;
283
284 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
285 return false;
286
287 Function::arg_iterator iter(F->getArgumentList().begin());
288
289 if (iter == F->getArgumentList().end())
290 return false;
291
292 llvm::Argument *argument = iter;
293
294 if (!argument->getName().equals("___clang_arg"))
295 return false;
296
297 if (log)
298 log->Printf("Arg: %s", PrintValue(argument).c_str());
299
300 llvm::BasicBlock &entry_block(F->getEntryBlock());
301 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
302
303 if (!first_entry_instruction)
304 return false;
305
306 LLVMContext &context(M.getContext());
307 const IntegerType *offset_type(Type::getInt32Ty(context));
308
309 if (!offset_type)
310 return false;
311
312 for (element_index = 0; element_index < num_elements; ++element_index)
313 {
314 const clang::NamedDecl *decl;
315 llvm::Value *value;
316 off_t offset;
317
318 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
319 return false;
320
321 if (log)
322 log->Printf(" %s (%s) placed at %d",
323 decl->getIdentifier()->getNameStart(),
324 PrintValue(value, true).c_str(),
325 offset);
326
327 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
328 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
329 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
330
Sean Callananbafd6852010-07-14 23:40:29 +0000331 if (Constant *constant = dyn_cast<Constant>(value))
332 UnfoldConstant(constant, bit_cast, first_entry_instruction);
333 else
334 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000335 }
336
337 if (log)
338 log->Printf("Total structure [align %d, size %d]", alignment, size);
339
340 return true;
341}
342
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000343bool
344IRForTarget::runOnModule(Module &M)
345{
346 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
347
348 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
349
350 if (!function)
351 {
352 if (log)
353 log->Printf("Couldn't find ___clang_expr() in the module");
354
355 return false;
356 }
357
358 llvm::Function::iterator bbi;
359
360 for (bbi = function->begin();
361 bbi != function->end();
362 ++bbi)
363 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000364 if (!runOnBasicBlock(M, *bbi))
365 return false;
366 }
367
368 if (!replaceVariables(M, function))
369 return false;
370
371 if (log)
372 {
373 for (bbi = function->begin();
374 bbi != function->end();
375 ++bbi)
376 {
377 log->Printf("Rewrote basic block %s for running: \n%s",
378 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
379 PrintValue(bbi).c_str());
380 }
381
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000382 }
383
384 return true;
385}
386
387void
388IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000389 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000390{
391}
392
393PassManagerType
394IRForTarget::getPotentialPassManagerType() const
395{
396 return PMT_ModulePassManager;
397}