blob: ce28a8f362c3cdba6bc09a5bbc91e78a0f33214f [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 Callanan45839272010-07-24 01:37:44 +0000165static bool isGuardVariableRef(llvm::Value *V)
166{
167 ConstantExpr *C = dyn_cast<ConstantExpr>(V);
168
169 if (!C || C->getOpcode() != Instruction::BitCast)
170 return false;
171
172 GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
173
174 if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
175 return false;
176
177 return true;
178}
179
180static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
181{
182 Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
183
184 Value::use_iterator ui;
185
186 for (ui = guard_load->use_begin();
187 ui != guard_load->use_end();
188 ++ui)
Sean Callananb5b749c2010-07-27 01:17:28 +0000189 {
190 if (isa<Constant>(ui))
191 {
192 // do nothing for the moment
193 }
194 else
195 {
196 ui->replaceUsesOfWith(guard_load, zero);
197 }
198 }
Sean Callanan45839272010-07-24 01:37:44 +0000199
200 guard_load->eraseFromParent();
201}
202
203static void ExciseGuardStore(Instruction* guard_store)
204{
205 guard_store->eraseFromParent();
206}
207
208bool
209IRForTarget::removeGuards(Module &M, BasicBlock &BB)
210{
211 ///////////////////////////////////////////////////////
212 // Eliminate any reference to guard variables found.
213 //
214
215 llvm::BasicBlock::iterator ii;
216
217 typedef llvm::SmallVector <Instruction*, 2> InstrList;
218 typedef InstrList::iterator InstrIterator;
219
220 InstrList guard_loads;
221 InstrList guard_stores;
222
223 for (ii = BB.begin();
224 ii != BB.end();
225 ++ii)
226 {
227 Instruction &inst = *ii;
228
229 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
230 if (isGuardVariableRef(load->getPointerOperand()))
231 guard_loads.push_back(&inst);
232
233 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
234 if (isGuardVariableRef(store->getPointerOperand()))
235 guard_stores.push_back(&inst);
236 }
237
238 InstrIterator iter;
239
240 for (iter = guard_loads.begin();
241 iter != guard_loads.end();
242 ++iter)
243 TurnGuardLoadIntoZero(*iter, M);
244
245 for (iter = guard_stores.begin();
246 iter != guard_stores.end();
247 ++iter)
248 ExciseGuardStore(*iter);
249
250 return true;
251}
252
Sean Callananbafd6852010-07-14 23:40:29 +0000253// UnfoldConstant operates on a constant [C] which has just been replaced with a value
254// [new_value]. We assume that new_value has been properly placed early in the function,
255// most likely somewhere in front of the first instruction in the entry basic block
256// [first_entry_instruction].
257//
258// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
259// Where those uses are constants, the function generates new instructions to compute the
260// result of the new, non-constant expression and places them before first_entry_instruction.
261// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
262// for those.
263
264static bool
265UnfoldConstant(llvm::Constant *C, llvm::Value *new_value, llvm::Instruction *first_entry_instruction)
266{
267 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
268
269 Value::use_iterator ui;
270
271 for (ui = C->use_begin();
272 ui != C->use_end();
273 ++ui)
274 {
275 User *user = *ui;
276
277 if (Constant *constant = dyn_cast<Constant>(user))
278 {
279 // synthesize a new non-constant equivalent of the constant
280
281 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
282 {
283 switch (constant_expr->getOpcode())
284 {
285 default:
286 if (log)
287 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
288 return false;
289 case Instruction::BitCast:
290 {
291 // UnaryExpr
292 // OperandList[0] is value
293
294 Value *s = constant_expr->getOperand(0);
295
296 if (s == C)
297 s = new_value;
298
299 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
300
301 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
302 }
303 break;
304 case Instruction::GetElementPtr:
305 {
306 // GetElementPtrConstantExpr
307 // OperandList[0] is base
308 // OperandList[1]... are indices
309
310 Value *ptr = constant_expr->getOperand(0);
311
312 if (ptr == C)
313 ptr = new_value;
314
315 SmallVector<Value*, 16> indices;
316
317 unsigned operand_index;
318 unsigned num_operands = constant_expr->getNumOperands();
319
320 for (operand_index = 1;
321 operand_index < num_operands;
322 ++operand_index)
323 {
324 Value *operand = constant_expr->getOperand(operand_index);
325
326 if (operand == C)
327 operand = new_value;
328
329 indices.push_back(operand);
330 }
331
332 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
333
334 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
335 }
336 break;
337 }
338 }
339 else
340 {
341 if (log)
342 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
343 return false;
344 }
345 }
346 else
347 {
348 // simple fall-through case for non-constants
349 user->replaceUsesOfWith(C, new_value);
350 }
351 }
352
353 return true;
354}
355
Sean Callanan8bce6652010-07-13 21:41:46 +0000356bool
357IRForTarget::replaceVariables(Module &M, Function *F)
358{
359 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
360
361 m_decl_map->DoStructLayout();
362
363 if (log)
364 log->Printf("Element arrangement:");
365
366 uint32_t num_elements;
367 uint32_t element_index;
368
369 size_t size;
370 off_t alignment;
371
372 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
373 return false;
374
375 Function::arg_iterator iter(F->getArgumentList().begin());
376
377 if (iter == F->getArgumentList().end())
378 return false;
379
380 llvm::Argument *argument = iter;
381
382 if (!argument->getName().equals("___clang_arg"))
383 return false;
384
385 if (log)
386 log->Printf("Arg: %s", PrintValue(argument).c_str());
387
388 llvm::BasicBlock &entry_block(F->getEntryBlock());
389 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
390
391 if (!first_entry_instruction)
392 return false;
393
394 LLVMContext &context(M.getContext());
395 const IntegerType *offset_type(Type::getInt32Ty(context));
396
397 if (!offset_type)
398 return false;
399
400 for (element_index = 0; element_index < num_elements; ++element_index)
401 {
402 const clang::NamedDecl *decl;
403 llvm::Value *value;
404 off_t offset;
405
406 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
407 return false;
408
409 if (log)
410 log->Printf(" %s (%s) placed at %d",
411 decl->getIdentifier()->getNameStart(),
412 PrintValue(value, true).c_str(),
413 offset);
414
415 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
416 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
417 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
418
Sean Callananbafd6852010-07-14 23:40:29 +0000419 if (Constant *constant = dyn_cast<Constant>(value))
420 UnfoldConstant(constant, bit_cast, first_entry_instruction);
421 else
422 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000423 }
424
425 if (log)
426 log->Printf("Total structure [align %d, size %d]", alignment, size);
427
428 return true;
429}
430
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000431bool
432IRForTarget::runOnModule(Module &M)
433{
434 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
435
436 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
437
438 if (!function)
439 {
440 if (log)
441 log->Printf("Couldn't find ___clang_expr() in the module");
442
443 return false;
444 }
445
446 llvm::Function::iterator bbi;
447
448 for (bbi = function->begin();
449 bbi != function->end();
450 ++bbi)
451 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000452 if (!runOnBasicBlock(M, *bbi))
453 return false;
Sean Callanan45839272010-07-24 01:37:44 +0000454
455 if (!removeGuards(M, *bbi))
456 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000457 }
458
459 if (!replaceVariables(M, function))
460 return false;
461
462 if (log)
463 {
464 for (bbi = function->begin();
465 bbi != function->end();
466 ++bbi)
467 {
468 log->Printf("Rewrote basic block %s for running: \n%s",
469 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
470 PrintValue(bbi).c_str());
471 }
472
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000473 }
474
475 return true;
476}
477
478void
479IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000480 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000481{
482}
483
484PassManagerType
485IRForTarget::getPotentialPassManagerType() const
486{
487 return PMT_ModulePassManager;
488}