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