blob: fb28a2ebf054f52e8444b5af87ae6a4e34b8c2b5 [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,
Sean Callanan02fbafa2010-07-27 21:39:39 +000032 const 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 *
Sean Callanan02fbafa2010-07-27 21:39:39 +000044DeclForGlobalValue(Module &module,
45 GlobalValue *global_value)
Sean Callanan8bce6652010-07-13 21:41:46 +000046{
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,
Sean Callanan02fbafa2010-07-27 21:39:39 +000085 Value *V,
Sean Callanan8bce6652010-07-13 21:41:46 +000086 bool Store)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000087{
Sean Callanan8bce6652010-07-13 21:41:46 +000088 if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
89 {
90 clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000091
Sean Callanan810f22d2010-07-16 00:09:46 +000092 std::string name = named_decl->getName().str();
93
94 void *qual_type = NULL;
Sean Callananf328c9f2010-07-20 23:31:16 +000095 clang::ASTContext *ast_context = NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +000096
97 if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
Sean Callananf328c9f2010-07-20 23:31:16 +000098 {
Sean Callanan810f22d2010-07-16 00:09:46 +000099 qual_type = value_decl->getType().getAsOpaquePtr();
Sean Callananf328c9f2010-07-20 23:31:16 +0000100 ast_context = &value_decl->getASTContext();
101 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000102 else
Sean Callananf328c9f2010-07-20 23:31:16 +0000103 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000104 return false;
Sean Callananf328c9f2010-07-20 23:31:16 +0000105 }
106
Sean Callanan02fbafa2010-07-27 21:39:39 +0000107 const Type *value_type = global_variable->getType();
Sean Callanan8bce6652010-07-13 21:41:46 +0000108
109 size_t value_size = m_target_data->getTypeStoreSize(value_type);
110 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
111
Sean Callananba992c52010-07-27 02:07:53 +0000112 if (named_decl && !m_decl_map->AddValueToStruct(V,
113 named_decl,
114 name,
115 qual_type,
116 ast_context,
117 value_size,
118 value_alignment))
Sean Callanan8bce6652010-07-13 21:41:46 +0000119 return false;
120 }
121
122 return true;
123}
124
125bool
Sean Callananba992c52010-07-27 02:07:53 +0000126IRForTarget::MaybeHandleCall(Module &M,
127 CallInst *C)
128{
129 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
130
Sean Callanan02fbafa2010-07-27 21:39:39 +0000131 Function *fun = C->getCalledFunction();
Sean Callananba992c52010-07-27 02:07:53 +0000132
133 if (fun == NULL)
134 return true;
135
136 clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun);
137
138 if (!fun_decl)
139 {
140 if (log)
141 log->Printf("Function %s wasn't in the metadata", fun->getName().str().c_str());
142 return false;
143 }
144
Sean Callanan02fbafa2010-07-27 21:39:39 +0000145 uint64_t fun_addr;
146 Value **fun_value_ptr;
Sean Callananba992c52010-07-27 02:07:53 +0000147
Sean Callanan02fbafa2010-07-27 21:39:39 +0000148 if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr))
Sean Callananba992c52010-07-27 02:07:53 +0000149 {
150 if (log)
151 log->Printf("Function %s had no address", fun_decl->getNameAsCString());
152 return false;
153 }
154
155 if (log)
156 log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr);
157
Sean Callanan02fbafa2010-07-27 21:39:39 +0000158 if (!*fun_value_ptr)
159 {
160 std::vector<const Type*> params;
161
162 const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(),
163 (M.getPointerSize() == Module::Pointer64) ? 64 : 32);
164
165 FunctionType *fun_ty = FunctionType::get(intptr_ty, params, true);
166 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
167 Constant *fun_addr_int = ConstantInt::get(intptr_ty, fun_addr, false);
168 Constant *fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
169 *fun_value_ptr = fun_addr_ptr;
170 }
171
172 C->setCalledFunction(*fun_value_ptr);
173
Sean Callananba992c52010-07-27 02:07:53 +0000174 return true;
175}
176
177bool
Sean Callanan8bce6652010-07-13 21:41:46 +0000178IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
179{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000180 /////////////////////////////////////////////////////////////////////////
181 // Prepare the current basic block for execution in the remote process
182 //
183
Sean Callanan02fbafa2010-07-27 21:39:39 +0000184 BasicBlock::iterator ii;
Sean Callanan8bce6652010-07-13 21:41:46 +0000185
186 for (ii = BB.begin();
187 ii != BB.end();
188 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000189 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000190 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000191
Sean Callanan8bce6652010-07-13 21:41:46 +0000192 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000193 if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
Sean Callanan8bce6652010-07-13 21:41:46 +0000194 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000195
Sean Callanan8bce6652010-07-13 21:41:46 +0000196 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000197 if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
198 return false;
199
200 if (CallInst *call = dyn_cast<CallInst>(&inst))
201 if (!MaybeHandleCall(M, call))
Sean Callanan8bce6652010-07-13 21:41:46 +0000202 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000203 }
204
205 return true;
206}
207
Sean Callananbafd6852010-07-14 23:40:29 +0000208static std::string
Sean Callanan02fbafa2010-07-27 21:39:39 +0000209PrintValue(Value *V, bool truncate = false)
Sean Callanan8bce6652010-07-13 21:41:46 +0000210{
211 std::string s;
212 raw_string_ostream rso(s);
213 V->print(rso);
214 rso.flush();
215 if (truncate)
216 s.resize(s.length() - 1);
217 return s;
218}
219
Sean Callanan02fbafa2010-07-27 21:39:39 +0000220static bool isGuardVariableRef(Value *V)
Sean Callanan45839272010-07-24 01:37:44 +0000221{
222 ConstantExpr *C = dyn_cast<ConstantExpr>(V);
223
224 if (!C || C->getOpcode() != Instruction::BitCast)
225 return false;
226
227 GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
228
229 if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
230 return false;
231
232 return true;
233}
234
235static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
236{
237 Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
238
239 Value::use_iterator ui;
240
241 for (ui = guard_load->use_begin();
242 ui != guard_load->use_end();
243 ++ui)
Sean Callananb5b749c2010-07-27 01:17:28 +0000244 {
Greg Clayton6e713402010-07-30 20:30:44 +0000245 if (isa<Constant>(*ui))
Sean Callananb5b749c2010-07-27 01:17:28 +0000246 {
247 // do nothing for the moment
248 }
249 else
250 {
251 ui->replaceUsesOfWith(guard_load, zero);
252 }
253 }
Sean Callanan45839272010-07-24 01:37:44 +0000254
255 guard_load->eraseFromParent();
256}
257
258static void ExciseGuardStore(Instruction* guard_store)
259{
260 guard_store->eraseFromParent();
261}
262
263bool
264IRForTarget::removeGuards(Module &M, BasicBlock &BB)
265{
266 ///////////////////////////////////////////////////////
267 // Eliminate any reference to guard variables found.
268 //
269
Sean Callanan02fbafa2010-07-27 21:39:39 +0000270 BasicBlock::iterator ii;
Sean Callanan45839272010-07-24 01:37:44 +0000271
Sean Callanan02fbafa2010-07-27 21:39:39 +0000272 typedef SmallVector <Instruction*, 2> InstrList;
Sean Callanan45839272010-07-24 01:37:44 +0000273 typedef InstrList::iterator InstrIterator;
274
275 InstrList guard_loads;
276 InstrList guard_stores;
277
278 for (ii = BB.begin();
279 ii != BB.end();
280 ++ii)
281 {
282 Instruction &inst = *ii;
283
284 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
285 if (isGuardVariableRef(load->getPointerOperand()))
286 guard_loads.push_back(&inst);
287
288 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
289 if (isGuardVariableRef(store->getPointerOperand()))
290 guard_stores.push_back(&inst);
291 }
292
293 InstrIterator iter;
294
295 for (iter = guard_loads.begin();
296 iter != guard_loads.end();
297 ++iter)
298 TurnGuardLoadIntoZero(*iter, M);
299
300 for (iter = guard_stores.begin();
301 iter != guard_stores.end();
302 ++iter)
303 ExciseGuardStore(*iter);
304
305 return true;
306}
307
Sean Callananbafd6852010-07-14 23:40:29 +0000308// UnfoldConstant operates on a constant [C] which has just been replaced with a value
309// [new_value]. We assume that new_value has been properly placed early in the function,
310// most likely somewhere in front of the first instruction in the entry basic block
311// [first_entry_instruction].
312//
313// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
314// Where those uses are constants, the function generates new instructions to compute the
315// result of the new, non-constant expression and places them before first_entry_instruction.
316// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
317// for those.
318
319static bool
Sean Callanan02fbafa2010-07-27 21:39:39 +0000320UnfoldConstant(Constant *C, Value *new_value, Instruction *first_entry_instruction)
Sean Callananbafd6852010-07-14 23:40:29 +0000321{
322 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
323
324 Value::use_iterator ui;
325
326 for (ui = C->use_begin();
327 ui != C->use_end();
328 ++ui)
329 {
330 User *user = *ui;
331
332 if (Constant *constant = dyn_cast<Constant>(user))
333 {
334 // synthesize a new non-constant equivalent of the constant
335
336 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
337 {
338 switch (constant_expr->getOpcode())
339 {
340 default:
341 if (log)
342 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
343 return false;
344 case Instruction::BitCast:
345 {
346 // UnaryExpr
347 // OperandList[0] is value
348
349 Value *s = constant_expr->getOperand(0);
350
351 if (s == C)
352 s = new_value;
353
354 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
355
356 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
357 }
358 break;
359 case Instruction::GetElementPtr:
360 {
361 // GetElementPtrConstantExpr
362 // OperandList[0] is base
363 // OperandList[1]... are indices
364
365 Value *ptr = constant_expr->getOperand(0);
366
367 if (ptr == C)
368 ptr = new_value;
369
370 SmallVector<Value*, 16> indices;
371
372 unsigned operand_index;
373 unsigned num_operands = constant_expr->getNumOperands();
374
375 for (operand_index = 1;
376 operand_index < num_operands;
377 ++operand_index)
378 {
379 Value *operand = constant_expr->getOperand(operand_index);
380
381 if (operand == C)
382 operand = new_value;
383
384 indices.push_back(operand);
385 }
386
387 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
388
389 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
390 }
391 break;
392 }
393 }
394 else
395 {
396 if (log)
397 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
398 return false;
399 }
400 }
401 else
402 {
403 // simple fall-through case for non-constants
404 user->replaceUsesOfWith(C, new_value);
405 }
406 }
407
408 return true;
409}
410
Sean Callanan8bce6652010-07-13 21:41:46 +0000411bool
412IRForTarget::replaceVariables(Module &M, Function *F)
413{
414 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
415
416 m_decl_map->DoStructLayout();
417
418 if (log)
419 log->Printf("Element arrangement:");
420
421 uint32_t num_elements;
422 uint32_t element_index;
423
424 size_t size;
425 off_t alignment;
426
427 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
428 return false;
429
430 Function::arg_iterator iter(F->getArgumentList().begin());
431
432 if (iter == F->getArgumentList().end())
433 return false;
434
Sean Callanan02fbafa2010-07-27 21:39:39 +0000435 Argument *argument = iter;
Sean Callanan8bce6652010-07-13 21:41:46 +0000436
437 if (!argument->getName().equals("___clang_arg"))
438 return false;
439
440 if (log)
441 log->Printf("Arg: %s", PrintValue(argument).c_str());
442
Sean Callanan02fbafa2010-07-27 21:39:39 +0000443 BasicBlock &entry_block(F->getEntryBlock());
444 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sean Callanan8bce6652010-07-13 21:41:46 +0000445
446 if (!first_entry_instruction)
447 return false;
448
449 LLVMContext &context(M.getContext());
450 const IntegerType *offset_type(Type::getInt32Ty(context));
451
452 if (!offset_type)
453 return false;
454
455 for (element_index = 0; element_index < num_elements; ++element_index)
456 {
457 const clang::NamedDecl *decl;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000458 Value *value;
Sean Callanan8bce6652010-07-13 21:41:46 +0000459 off_t offset;
460
461 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
462 return false;
463
464 if (log)
465 log->Printf(" %s (%s) placed at %d",
466 decl->getIdentifier()->getNameStart(),
467 PrintValue(value, true).c_str(),
468 offset);
469
470 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
471 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
472 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
473
Sean Callananbafd6852010-07-14 23:40:29 +0000474 if (Constant *constant = dyn_cast<Constant>(value))
475 UnfoldConstant(constant, bit_cast, first_entry_instruction);
476 else
477 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000478 }
479
480 if (log)
481 log->Printf("Total structure [align %d, size %d]", alignment, size);
482
483 return true;
484}
485
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000486bool
487IRForTarget::runOnModule(Module &M)
488{
489 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
490
Sean Callanan02fbafa2010-07-27 21:39:39 +0000491 Function* function = M.getFunction(StringRef("___clang_expr"));
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000492
493 if (!function)
494 {
495 if (log)
496 log->Printf("Couldn't find ___clang_expr() in the module");
497
498 return false;
499 }
500
Sean Callanan02fbafa2010-07-27 21:39:39 +0000501 Function::iterator bbi;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000502
503 for (bbi = function->begin();
504 bbi != function->end();
505 ++bbi)
506 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000507 if (!runOnBasicBlock(M, *bbi))
508 return false;
Sean Callanan45839272010-07-24 01:37:44 +0000509
510 if (!removeGuards(M, *bbi))
511 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000512 }
513
Sean Callanan321fe9e2010-07-28 01:00:59 +0000514 // TEMPORARY FOR DEBUGGING
515 M.dump();
516
Sean Callanan8bce6652010-07-13 21:41:46 +0000517 if (!replaceVariables(M, function))
518 return false;
519
520 if (log)
521 {
Sean Callanan321fe9e2010-07-28 01:00:59 +0000522 std::string s;
523 raw_string_ostream oss(s);
Sean Callanan8bce6652010-07-13 21:41:46 +0000524
Sean Callanan321fe9e2010-07-28 01:00:59 +0000525 M.print(oss, NULL);
526
527 oss.flush();
528
529 log->Printf("Module after preparing for execution: \n%s", s.c_str());
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000530 }
531
532 return true;
533}
534
535void
536IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000537 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000538{
539}
540
541PassManagerType
542IRForTarget::getPotentialPassManagerType() const
543{
544 return PMT_ModulePassManager;
545}