blob: 4f5d44c70a18d9529722aca19292917d0382a687 [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,
Sean Callanan8bce6652010-07-13 21:41:46 +000085 llvm::Value *V,
86 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 Callanan8bce6652010-07-13 21:41:46 +0000107 const llvm::Type *value_type = global_variable->getType();
108
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
131 llvm::Function *fun = C->getCalledFunction();
132
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
145 uint64_t fun_addr = m_decl_map->GetFunctionAddress(fun_decl);
146
147 if (fun_addr == 0)
148 {
149 if (log)
150 log->Printf("Function %s had no address", fun_decl->getNameAsCString());
151 return false;
152 }
153
154 if (log)
155 log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr);
156
157 return true;
158}
159
160bool
Sean Callanan8bce6652010-07-13 21:41:46 +0000161IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
162{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000163 /////////////////////////////////////////////////////////////////////////
164 // Prepare the current basic block for execution in the remote process
165 //
166
Sean Callanan8bce6652010-07-13 21:41:46 +0000167 llvm::BasicBlock::iterator ii;
168
169 for (ii = BB.begin();
170 ii != BB.end();
171 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000172 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000173 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000174
Sean Callanan8bce6652010-07-13 21:41:46 +0000175 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000176 if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
Sean Callanan8bce6652010-07-13 21:41:46 +0000177 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000178
Sean Callanan8bce6652010-07-13 21:41:46 +0000179 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000180 if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
181 return false;
182
183 if (CallInst *call = dyn_cast<CallInst>(&inst))
184 if (!MaybeHandleCall(M, call))
Sean Callanan8bce6652010-07-13 21:41:46 +0000185 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000186 }
187
188 return true;
189}
190
Sean Callananbafd6852010-07-14 23:40:29 +0000191static std::string
192PrintValue(llvm::Value *V, bool truncate = false)
Sean Callanan8bce6652010-07-13 21:41:46 +0000193{
194 std::string s;
195 raw_string_ostream rso(s);
196 V->print(rso);
197 rso.flush();
198 if (truncate)
199 s.resize(s.length() - 1);
200 return s;
201}
202
Sean Callanan45839272010-07-24 01:37:44 +0000203static bool isGuardVariableRef(llvm::Value *V)
204{
205 ConstantExpr *C = dyn_cast<ConstantExpr>(V);
206
207 if (!C || C->getOpcode() != Instruction::BitCast)
208 return false;
209
210 GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
211
212 if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
213 return false;
214
215 return true;
216}
217
218static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
219{
220 Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
221
222 Value::use_iterator ui;
223
224 for (ui = guard_load->use_begin();
225 ui != guard_load->use_end();
226 ++ui)
Sean Callananb5b749c2010-07-27 01:17:28 +0000227 {
228 if (isa<Constant>(ui))
229 {
230 // do nothing for the moment
231 }
232 else
233 {
234 ui->replaceUsesOfWith(guard_load, zero);
235 }
236 }
Sean Callanan45839272010-07-24 01:37:44 +0000237
238 guard_load->eraseFromParent();
239}
240
241static void ExciseGuardStore(Instruction* guard_store)
242{
243 guard_store->eraseFromParent();
244}
245
246bool
247IRForTarget::removeGuards(Module &M, BasicBlock &BB)
248{
249 ///////////////////////////////////////////////////////
250 // Eliminate any reference to guard variables found.
251 //
252
253 llvm::BasicBlock::iterator ii;
254
255 typedef llvm::SmallVector <Instruction*, 2> InstrList;
256 typedef InstrList::iterator InstrIterator;
257
258 InstrList guard_loads;
259 InstrList guard_stores;
260
261 for (ii = BB.begin();
262 ii != BB.end();
263 ++ii)
264 {
265 Instruction &inst = *ii;
266
267 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
268 if (isGuardVariableRef(load->getPointerOperand()))
269 guard_loads.push_back(&inst);
270
271 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
272 if (isGuardVariableRef(store->getPointerOperand()))
273 guard_stores.push_back(&inst);
274 }
275
276 InstrIterator iter;
277
278 for (iter = guard_loads.begin();
279 iter != guard_loads.end();
280 ++iter)
281 TurnGuardLoadIntoZero(*iter, M);
282
283 for (iter = guard_stores.begin();
284 iter != guard_stores.end();
285 ++iter)
286 ExciseGuardStore(*iter);
287
288 return true;
289}
290
Sean Callananbafd6852010-07-14 23:40:29 +0000291// UnfoldConstant operates on a constant [C] which has just been replaced with a value
292// [new_value]. We assume that new_value has been properly placed early in the function,
293// most likely somewhere in front of the first instruction in the entry basic block
294// [first_entry_instruction].
295//
296// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
297// Where those uses are constants, the function generates new instructions to compute the
298// result of the new, non-constant expression and places them before first_entry_instruction.
299// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
300// for those.
301
302static bool
303UnfoldConstant(llvm::Constant *C, llvm::Value *new_value, llvm::Instruction *first_entry_instruction)
304{
305 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
306
307 Value::use_iterator ui;
308
309 for (ui = C->use_begin();
310 ui != C->use_end();
311 ++ui)
312 {
313 User *user = *ui;
314
315 if (Constant *constant = dyn_cast<Constant>(user))
316 {
317 // synthesize a new non-constant equivalent of the constant
318
319 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
320 {
321 switch (constant_expr->getOpcode())
322 {
323 default:
324 if (log)
325 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
326 return false;
327 case Instruction::BitCast:
328 {
329 // UnaryExpr
330 // OperandList[0] is value
331
332 Value *s = constant_expr->getOperand(0);
333
334 if (s == C)
335 s = new_value;
336
337 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
338
339 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
340 }
341 break;
342 case Instruction::GetElementPtr:
343 {
344 // GetElementPtrConstantExpr
345 // OperandList[0] is base
346 // OperandList[1]... are indices
347
348 Value *ptr = constant_expr->getOperand(0);
349
350 if (ptr == C)
351 ptr = new_value;
352
353 SmallVector<Value*, 16> indices;
354
355 unsigned operand_index;
356 unsigned num_operands = constant_expr->getNumOperands();
357
358 for (operand_index = 1;
359 operand_index < num_operands;
360 ++operand_index)
361 {
362 Value *operand = constant_expr->getOperand(operand_index);
363
364 if (operand == C)
365 operand = new_value;
366
367 indices.push_back(operand);
368 }
369
370 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
371
372 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
373 }
374 break;
375 }
376 }
377 else
378 {
379 if (log)
380 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
381 return false;
382 }
383 }
384 else
385 {
386 // simple fall-through case for non-constants
387 user->replaceUsesOfWith(C, new_value);
388 }
389 }
390
391 return true;
392}
393
Sean Callanan8bce6652010-07-13 21:41:46 +0000394bool
395IRForTarget::replaceVariables(Module &M, Function *F)
396{
397 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
398
399 m_decl_map->DoStructLayout();
400
401 if (log)
402 log->Printf("Element arrangement:");
403
404 uint32_t num_elements;
405 uint32_t element_index;
406
407 size_t size;
408 off_t alignment;
409
410 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
411 return false;
412
413 Function::arg_iterator iter(F->getArgumentList().begin());
414
415 if (iter == F->getArgumentList().end())
416 return false;
417
418 llvm::Argument *argument = iter;
419
420 if (!argument->getName().equals("___clang_arg"))
421 return false;
422
423 if (log)
424 log->Printf("Arg: %s", PrintValue(argument).c_str());
425
426 llvm::BasicBlock &entry_block(F->getEntryBlock());
427 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
428
429 if (!first_entry_instruction)
430 return false;
431
432 LLVMContext &context(M.getContext());
433 const IntegerType *offset_type(Type::getInt32Ty(context));
434
435 if (!offset_type)
436 return false;
437
438 for (element_index = 0; element_index < num_elements; ++element_index)
439 {
440 const clang::NamedDecl *decl;
441 llvm::Value *value;
442 off_t offset;
443
444 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
445 return false;
446
447 if (log)
448 log->Printf(" %s (%s) placed at %d",
449 decl->getIdentifier()->getNameStart(),
450 PrintValue(value, true).c_str(),
451 offset);
452
453 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
454 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
455 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
456
Sean Callananbafd6852010-07-14 23:40:29 +0000457 if (Constant *constant = dyn_cast<Constant>(value))
458 UnfoldConstant(constant, bit_cast, first_entry_instruction);
459 else
460 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000461 }
462
463 if (log)
464 log->Printf("Total structure [align %d, size %d]", alignment, size);
465
466 return true;
467}
468
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000469bool
470IRForTarget::runOnModule(Module &M)
471{
472 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
473
474 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
475
476 if (!function)
477 {
478 if (log)
479 log->Printf("Couldn't find ___clang_expr() in the module");
480
481 return false;
482 }
483
484 llvm::Function::iterator bbi;
485
486 for (bbi = function->begin();
487 bbi != function->end();
488 ++bbi)
489 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000490 if (!runOnBasicBlock(M, *bbi))
491 return false;
Sean Callanan45839272010-07-24 01:37:44 +0000492
493 if (!removeGuards(M, *bbi))
494 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000495 }
496
497 if (!replaceVariables(M, function))
498 return false;
499
500 if (log)
501 {
502 for (bbi = function->begin();
503 bbi != function->end();
504 ++bbi)
505 {
506 log->Printf("Rewrote basic block %s for running: \n%s",
507 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
508 PrintValue(bbi).c_str());
509 }
510
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000511 }
512
513 return true;
514}
515
516void
517IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000518 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000519{
520}
521
522PassManagerType
523IRForTarget::getPotentialPassManagerType() const
524{
525 return PMT_ModulePassManager;
526}