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