blob: 4f3a740e0bb71ecb8a23d0aeea9d0fdc16871223 [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),
Sean Callananf5857a02010-07-31 01:32:05 +000035 m_target_data(target_data),
36 m_sel_registerName(NULL)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000037{
38}
39
40IRForTarget::~IRForTarget()
41{
42}
43
Sean Callananf5857a02010-07-31 01:32:05 +000044static bool isObjCSelectorRef(Value *V)
45{
46 GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
47
48 if (!GV || !GV->hasName() || !GV->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_"))
49 return false;
50
51 return true;
52}
53
54bool
55IRForTarget::RewriteObjCSelector(Instruction* selector_load,
56 Module &M)
57{
58 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
59
60 LoadInst *load = dyn_cast<LoadInst>(selector_load);
61
62 if (!load)
63 return false;
64
65 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as
66 //
67 // %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*>
68 // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
69 //
70 // where %obj is the object pointer and %tmp is the selector.
71 //
72 // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_METH_VAR_NAME_".
73 // @"\01L_OBJC_METH_VAR_NAME_" contains the string.
74
75 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
76
77 GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
78
79 if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
80 return false;
81
82 Constant *osr_initializer = _objc_selector_references_->getInitializer();
83
84 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
85
86 if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
87 return false;
88
89 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
90
91 if (!osr_initializer_base)
92 return false;
93
94 // Find the string's initializer (a ConstantArray) and get the string from it
95
96 GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
97
98 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
99 return false;
100
101 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
102
103 ConstantArray *omvn_initializer_array = dyn_cast<ConstantArray>(omvn_initializer);
104
105 if (!omvn_initializer_array->isString())
106 return false;
107
108 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
109
110 if (log)
111 log->Printf("Found Objective-C selector reference %s", omvn_initializer_string.c_str());
112
113 // Construct a call to sel_registerName
114
115 if (!m_sel_registerName)
116 {
117 uint64_t srN_addr;
118
119 if (!m_decl_map->GetFunctionAddress("sel_registerName", srN_addr))
120 return false;
121
122 // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
123
124 // The below code would be "more correct," but in actuality what's required is uint8_t*
125 //Type *sel_type = StructType::get(M.getContext());
126 //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
127 const Type *sel_ptr_type = Type::getInt8PtrTy(M.getContext());
128
129 std::vector <const Type *> srN_arg_types;
130 srN_arg_types.push_back(Type::getInt8PtrTy(M.getContext()));
131 llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
132
133 // Build the constant containing the pointer to the function
134 const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(),
135 (M.getPointerSize() == Module::Pointer64) ? 64 : 32);
136 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
137 Constant *srN_addr_int = ConstantInt::get(intptr_ty, srN_addr, false);
138 m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
139 }
140
141 SmallVector <Value*, 1> srN_arguments;
142
143 Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(M.getContext()));
144
145 srN_arguments.push_back(omvn_pointer);
146
147 CallInst *srN_call = CallInst::Create(m_sel_registerName,
148 srN_arguments.begin(),
149 srN_arguments.end(),
150 "srN",
151 selector_load);
152
153 // Replace the load with the call in all users
154
155 selector_load->replaceAllUsesWith(srN_call);
156
157 selector_load->eraseFromParent();
158
159 return true;
160}
161
162bool
163IRForTarget::rewriteObjCSelectors(Module &M,
164 BasicBlock &BB)
165{
166 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
167
168 BasicBlock::iterator ii;
169
170 typedef SmallVector <Instruction*, 2> InstrList;
171 typedef InstrList::iterator InstrIterator;
172
173 InstrList selector_loads;
174
175 for (ii = BB.begin();
176 ii != BB.end();
177 ++ii)
178 {
179 Instruction &inst = *ii;
180
181 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
182 if (isObjCSelectorRef(load->getPointerOperand()))
183 selector_loads.push_back(&inst);
184 }
185
186 InstrIterator iter;
187
188 for (iter = selector_loads.begin();
189 iter != selector_loads.end();
190 ++iter)
191 {
192 if (!RewriteObjCSelector(*iter, M))
193 {
194 if(log)
195 log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
196 return false;
197 }
198 }
199
200 return true;
201}
202
Sean Callanan8bce6652010-07-13 21:41:46 +0000203static clang::NamedDecl *
Sean Callanan02fbafa2010-07-27 21:39:39 +0000204DeclForGlobalValue(Module &module,
205 GlobalValue *global_value)
Sean Callanan8bce6652010-07-13 21:41:46 +0000206{
207 NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs");
208
209 if (!named_metadata)
210 return NULL;
211
212 unsigned num_nodes = named_metadata->getNumOperands();
213 unsigned node_index;
214
215 for (node_index = 0;
216 node_index < num_nodes;
217 ++node_index)
218 {
219 MDNode *metadata_node = named_metadata->getOperand(node_index);
220
221 if (!metadata_node)
222 return NULL;
223
224 if (metadata_node->getNumOperands() != 2)
225 return NULL;
226
227 if (metadata_node->getOperand(0) != global_value)
228 continue;
229
230 ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
231
232 if (!constant_int)
233 return NULL;
234
235 uintptr_t ptr = constant_int->getZExtValue();
236
237 return reinterpret_cast<clang::NamedDecl *>(ptr);
238 }
239
240 return NULL;
241}
242
243bool
244IRForTarget::MaybeHandleVariable(Module &M,
Sean Callanan02fbafa2010-07-27 21:39:39 +0000245 Value *V,
Sean Callanan8bce6652010-07-13 21:41:46 +0000246 bool Store)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000247{
Sean Callananf5857a02010-07-31 01:32:05 +0000248 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
249
Sean Callananbc2928a2010-08-03 00:23:29 +0000250 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(V))
251 {
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000252 switch (constant_expr->getOpcode())
Sean Callananbc2928a2010-08-03 00:23:29 +0000253 {
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000254 default:
255 break;
256 case Instruction::GetElementPtr:
257 case Instruction::BitCast:
Sean Callananbc2928a2010-08-03 00:23:29 +0000258 Value *s = constant_expr->getOperand(0);
259 MaybeHandleVariable(M, s, Store);
260 }
261 }
Sean Callanan8bce6652010-07-13 21:41:46 +0000262 if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
Sean Callananf5857a02010-07-31 01:32:05 +0000263 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000264 clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000265
Sean Callananf5857a02010-07-31 01:32:05 +0000266 if (!named_decl)
267 {
268 if (isObjCSelectorRef(V))
269 return true;
270
271 if (log)
272 log->Printf("Found global variable %s without metadata", global_variable->getName().str().c_str());
273 return false;
274 }
275
Sean Callanan810f22d2010-07-16 00:09:46 +0000276 std::string name = named_decl->getName().str();
277
278 void *qual_type = NULL;
Sean Callananf328c9f2010-07-20 23:31:16 +0000279 clang::ASTContext *ast_context = NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000280
281 if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
Sean Callananf328c9f2010-07-20 23:31:16 +0000282 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000283 qual_type = value_decl->getType().getAsOpaquePtr();
Sean Callananf328c9f2010-07-20 23:31:16 +0000284 ast_context = &value_decl->getASTContext();
285 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000286 else
Sean Callananf328c9f2010-07-20 23:31:16 +0000287 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000288 return false;
Sean Callananf328c9f2010-07-20 23:31:16 +0000289 }
290
Sean Callanan02fbafa2010-07-27 21:39:39 +0000291 const Type *value_type = global_variable->getType();
Sean Callanan8bce6652010-07-13 21:41:46 +0000292
293 size_t value_size = m_target_data->getTypeStoreSize(value_type);
294 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
295
Sean Callananba992c52010-07-27 02:07:53 +0000296 if (named_decl && !m_decl_map->AddValueToStruct(V,
297 named_decl,
298 name,
299 qual_type,
300 ast_context,
301 value_size,
302 value_alignment))
Sean Callanan8bce6652010-07-13 21:41:46 +0000303 return false;
304 }
305
306 return true;
307}
308
309bool
Sean Callananba992c52010-07-27 02:07:53 +0000310IRForTarget::MaybeHandleCall(Module &M,
311 CallInst *C)
312{
313 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
314
Sean Callanan02fbafa2010-07-27 21:39:39 +0000315 Function *fun = C->getCalledFunction();
Sean Callananba992c52010-07-27 02:07:53 +0000316
317 if (fun == NULL)
318 return true;
319
320 clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun);
Sean Callanan02fbafa2010-07-27 21:39:39 +0000321 uint64_t fun_addr;
Sean Callananf5857a02010-07-31 01:32:05 +0000322 Value **fun_value_ptr = NULL;
Sean Callananba992c52010-07-27 02:07:53 +0000323
Sean Callananf5857a02010-07-31 01:32:05 +0000324 if (fun_decl)
Sean Callananba992c52010-07-27 02:07:53 +0000325 {
Sean Callananf5857a02010-07-31 01:32:05 +0000326 if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr))
327 {
328 if (log)
329 log->Printf("Function %s had no address", fun_decl->getNameAsCString());
330 return false;
331 }
332 }
333 else
334 {
335 if (!m_decl_map->GetFunctionAddress(fun->getName().str().c_str(), fun_addr))
336 {
337 if (log)
338 log->Printf("Metadataless function %s had no address", fun->getName().str().c_str());
339 return false;
340 }
Sean Callananba992c52010-07-27 02:07:53 +0000341 }
342
343 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000344 log->Printf("Found %s at %llx", fun->getName().str().c_str(), fun_addr);
Sean Callananba992c52010-07-27 02:07:53 +0000345
Sean Callananf5857a02010-07-31 01:32:05 +0000346 Value *fun_addr_ptr;
347
348 if (!fun_value_ptr || !*fun_value_ptr)
Sean Callanan02fbafa2010-07-27 21:39:39 +0000349 {
350 std::vector<const Type*> params;
351
352 const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(),
353 (M.getPointerSize() == Module::Pointer64) ? 64 : 32);
354
355 FunctionType *fun_ty = FunctionType::get(intptr_ty, params, true);
356 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
357 Constant *fun_addr_int = ConstantInt::get(intptr_ty, fun_addr, false);
Sean Callananf5857a02010-07-31 01:32:05 +0000358 fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
359
360 if (fun_value_ptr)
361 *fun_value_ptr = fun_addr_ptr;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000362 }
Sean Callananf5857a02010-07-31 01:32:05 +0000363
364 if (fun_value_ptr)
365 fun_addr_ptr = *fun_value_ptr;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000366
Sean Callananf5857a02010-07-31 01:32:05 +0000367 C->setCalledFunction(fun_addr_ptr);
Sean Callanan02fbafa2010-07-27 21:39:39 +0000368
Sean Callananba992c52010-07-27 02:07:53 +0000369 return true;
370}
371
372bool
Sean Callananf5857a02010-07-31 01:32:05 +0000373IRForTarget::resolveExternals(Module &M, BasicBlock &BB)
Sean Callanan8bce6652010-07-13 21:41:46 +0000374{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000375 /////////////////////////////////////////////////////////////////////////
376 // Prepare the current basic block for execution in the remote process
377 //
378
Sean Callanan02fbafa2010-07-27 21:39:39 +0000379 BasicBlock::iterator ii;
Sean Callanan8bce6652010-07-13 21:41:46 +0000380
381 for (ii = BB.begin();
382 ii != BB.end();
383 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000384 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000385 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000386
Sean Callanan8bce6652010-07-13 21:41:46 +0000387 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000388 if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
Sean Callanan8bce6652010-07-13 21:41:46 +0000389 return false;
Sean Callananf5857a02010-07-31 01:32:05 +0000390
Sean Callanan8bce6652010-07-13 21:41:46 +0000391 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000392 if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
393 return false;
394
395 if (CallInst *call = dyn_cast<CallInst>(&inst))
396 if (!MaybeHandleCall(M, call))
Sean Callanan8bce6652010-07-13 21:41:46 +0000397 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000398 }
399
400 return true;
401}
402
Sean Callananbafd6852010-07-14 23:40:29 +0000403static std::string
Sean Callanan02fbafa2010-07-27 21:39:39 +0000404PrintValue(Value *V, bool truncate = false)
Sean Callanan8bce6652010-07-13 21:41:46 +0000405{
406 std::string s;
407 raw_string_ostream rso(s);
408 V->print(rso);
409 rso.flush();
410 if (truncate)
411 s.resize(s.length() - 1);
412 return s;
413}
414
Sean Callanan02fbafa2010-07-27 21:39:39 +0000415static bool isGuardVariableRef(Value *V)
Sean Callanan45839272010-07-24 01:37:44 +0000416{
417 ConstantExpr *C = dyn_cast<ConstantExpr>(V);
418
419 if (!C || C->getOpcode() != Instruction::BitCast)
420 return false;
421
422 GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
423
424 if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
425 return false;
426
427 return true;
428}
429
430static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
431{
432 Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
433
434 Value::use_iterator ui;
435
436 for (ui = guard_load->use_begin();
437 ui != guard_load->use_end();
438 ++ui)
Sean Callananb5b749c2010-07-27 01:17:28 +0000439 {
Greg Clayton6e713402010-07-30 20:30:44 +0000440 if (isa<Constant>(*ui))
Sean Callananb5b749c2010-07-27 01:17:28 +0000441 {
442 // do nothing for the moment
443 }
444 else
445 {
446 ui->replaceUsesOfWith(guard_load, zero);
447 }
448 }
Sean Callanan45839272010-07-24 01:37:44 +0000449
450 guard_load->eraseFromParent();
451}
452
453static void ExciseGuardStore(Instruction* guard_store)
454{
455 guard_store->eraseFromParent();
456}
457
458bool
459IRForTarget::removeGuards(Module &M, BasicBlock &BB)
460{
461 ///////////////////////////////////////////////////////
462 // Eliminate any reference to guard variables found.
463 //
464
Sean Callanan02fbafa2010-07-27 21:39:39 +0000465 BasicBlock::iterator ii;
Sean Callanan45839272010-07-24 01:37:44 +0000466
Sean Callanan02fbafa2010-07-27 21:39:39 +0000467 typedef SmallVector <Instruction*, 2> InstrList;
Sean Callanan45839272010-07-24 01:37:44 +0000468 typedef InstrList::iterator InstrIterator;
469
470 InstrList guard_loads;
471 InstrList guard_stores;
472
473 for (ii = BB.begin();
474 ii != BB.end();
475 ++ii)
476 {
477 Instruction &inst = *ii;
478
479 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
480 if (isGuardVariableRef(load->getPointerOperand()))
481 guard_loads.push_back(&inst);
482
483 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
484 if (isGuardVariableRef(store->getPointerOperand()))
485 guard_stores.push_back(&inst);
486 }
487
488 InstrIterator iter;
489
490 for (iter = guard_loads.begin();
491 iter != guard_loads.end();
492 ++iter)
493 TurnGuardLoadIntoZero(*iter, M);
494
495 for (iter = guard_stores.begin();
496 iter != guard_stores.end();
497 ++iter)
498 ExciseGuardStore(*iter);
499
500 return true;
501}
502
Sean Callananbafd6852010-07-14 23:40:29 +0000503// UnfoldConstant operates on a constant [C] which has just been replaced with a value
504// [new_value]. We assume that new_value has been properly placed early in the function,
505// most likely somewhere in front of the first instruction in the entry basic block
506// [first_entry_instruction].
507//
508// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
509// Where those uses are constants, the function generates new instructions to compute the
510// result of the new, non-constant expression and places them before first_entry_instruction.
511// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
512// for those.
513
514static bool
Sean Callanan02fbafa2010-07-27 21:39:39 +0000515UnfoldConstant(Constant *C, Value *new_value, Instruction *first_entry_instruction)
Sean Callananbafd6852010-07-14 23:40:29 +0000516{
517 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
518
519 Value::use_iterator ui;
520
521 for (ui = C->use_begin();
522 ui != C->use_end();
523 ++ui)
524 {
525 User *user = *ui;
526
527 if (Constant *constant = dyn_cast<Constant>(user))
528 {
529 // synthesize a new non-constant equivalent of the constant
530
531 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
532 {
533 switch (constant_expr->getOpcode())
534 {
535 default:
536 if (log)
537 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
538 return false;
539 case Instruction::BitCast:
540 {
541 // UnaryExpr
542 // OperandList[0] is value
543
544 Value *s = constant_expr->getOperand(0);
545
546 if (s == C)
547 s = new_value;
548
549 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
550
551 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
552 }
553 break;
554 case Instruction::GetElementPtr:
555 {
556 // GetElementPtrConstantExpr
557 // OperandList[0] is base
558 // OperandList[1]... are indices
559
560 Value *ptr = constant_expr->getOperand(0);
561
562 if (ptr == C)
563 ptr = new_value;
564
565 SmallVector<Value*, 16> indices;
566
567 unsigned operand_index;
568 unsigned num_operands = constant_expr->getNumOperands();
569
570 for (operand_index = 1;
571 operand_index < num_operands;
572 ++operand_index)
573 {
574 Value *operand = constant_expr->getOperand(operand_index);
575
576 if (operand == C)
577 operand = new_value;
578
579 indices.push_back(operand);
580 }
581
582 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
583
584 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
585 }
586 break;
587 }
588 }
589 else
590 {
591 if (log)
592 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
593 return false;
594 }
595 }
596 else
597 {
598 // simple fall-through case for non-constants
599 user->replaceUsesOfWith(C, new_value);
600 }
601 }
602
603 return true;
604}
605
Sean Callanan8bce6652010-07-13 21:41:46 +0000606bool
Sean Callananf5857a02010-07-31 01:32:05 +0000607IRForTarget::replaceVariables(Module &M, Function &F)
Sean Callanan8bce6652010-07-13 21:41:46 +0000608{
609 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
610
611 m_decl_map->DoStructLayout();
612
613 if (log)
614 log->Printf("Element arrangement:");
615
616 uint32_t num_elements;
617 uint32_t element_index;
618
619 size_t size;
620 off_t alignment;
621
622 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
623 return false;
624
Sean Callananf5857a02010-07-31 01:32:05 +0000625 Function::arg_iterator iter(F.getArgumentList().begin());
Sean Callanan8bce6652010-07-13 21:41:46 +0000626
Sean Callananf5857a02010-07-31 01:32:05 +0000627 if (iter == F.getArgumentList().end())
Sean Callanan8bce6652010-07-13 21:41:46 +0000628 return false;
629
Sean Callanan02fbafa2010-07-27 21:39:39 +0000630 Argument *argument = iter;
Sean Callanan8bce6652010-07-13 21:41:46 +0000631
632 if (!argument->getName().equals("___clang_arg"))
633 return false;
634
635 if (log)
636 log->Printf("Arg: %s", PrintValue(argument).c_str());
637
Sean Callananf5857a02010-07-31 01:32:05 +0000638 BasicBlock &entry_block(F.getEntryBlock());
Sean Callanan02fbafa2010-07-27 21:39:39 +0000639 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sean Callanan8bce6652010-07-13 21:41:46 +0000640
641 if (!first_entry_instruction)
642 return false;
643
644 LLVMContext &context(M.getContext());
645 const IntegerType *offset_type(Type::getInt32Ty(context));
646
647 if (!offset_type)
648 return false;
649
650 for (element_index = 0; element_index < num_elements; ++element_index)
651 {
652 const clang::NamedDecl *decl;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000653 Value *value;
Sean Callanan8bce6652010-07-13 21:41:46 +0000654 off_t offset;
655
656 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
657 return false;
658
659 if (log)
660 log->Printf(" %s (%s) placed at %d",
661 decl->getIdentifier()->getNameStart(),
662 PrintValue(value, true).c_str(),
663 offset);
664
665 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
666 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
667 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
668
Sean Callananbafd6852010-07-14 23:40:29 +0000669 if (Constant *constant = dyn_cast<Constant>(value))
670 UnfoldConstant(constant, bit_cast, first_entry_instruction);
671 else
672 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000673 }
674
675 if (log)
676 log->Printf("Total structure [align %d, size %d]", alignment, size);
677
678 return true;
679}
680
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000681bool
682IRForTarget::runOnModule(Module &M)
683{
684 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
685
Sean Callanan02fbafa2010-07-27 21:39:39 +0000686 Function* function = M.getFunction(StringRef("___clang_expr"));
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000687
688 if (!function)
689 {
690 if (log)
691 log->Printf("Couldn't find ___clang_expr() in the module");
692
693 return false;
694 }
695
Sean Callanan02fbafa2010-07-27 21:39:39 +0000696 Function::iterator bbi;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000697
Sean Callananf5857a02010-07-31 01:32:05 +0000698 //////////////////////////////////
699 // Run basic-block level passes
700 //
701
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000702 for (bbi = function->begin();
703 bbi != function->end();
704 ++bbi)
705 {
Sean Callananf5857a02010-07-31 01:32:05 +0000706 if (!rewriteObjCSelectors(M, *bbi))
707 return false;
708
709 if (!resolveExternals(M, *bbi))
Sean Callanan8bce6652010-07-13 21:41:46 +0000710 return false;
Sean Callanan45839272010-07-24 01:37:44 +0000711
712 if (!removeGuards(M, *bbi))
713 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000714 }
715
Sean Callananf5857a02010-07-31 01:32:05 +0000716 ///////////////////////////////
717 // Run function-level passes
718 //
Sean Callanan321fe9e2010-07-28 01:00:59 +0000719
Sean Callananf5857a02010-07-31 01:32:05 +0000720 if (!replaceVariables(M, *function))
Sean Callanan8bce6652010-07-13 21:41:46 +0000721 return false;
722
723 if (log)
724 {
Sean Callanan321fe9e2010-07-28 01:00:59 +0000725 std::string s;
726 raw_string_ostream oss(s);
Sean Callanan8bce6652010-07-13 21:41:46 +0000727
Sean Callanan321fe9e2010-07-28 01:00:59 +0000728 M.print(oss, NULL);
729
730 oss.flush();
731
732 log->Printf("Module after preparing for execution: \n%s", s.c_str());
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000733 }
734
735 return true;
736}
737
738void
739IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000740 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000741{
742}
743
744PassManagerType
745IRForTarget::getPotentialPassManagerType() const
746{
747 return PMT_ModulePassManager;
748}