blob: 9541945eebc00da504800c0719e3ad151d674c65 [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
Sean Callanana48fe162010-08-11 03:57:18 +000040/* A handy utility function used at several places in the code */
41
42static std::string
43PrintValue(Value *V, bool truncate = false)
44{
45 std::string s;
46 raw_string_ostream rso(s);
47 V->print(rso);
48 rso.flush();
49 if (truncate)
50 s.resize(s.length() - 1);
51 return s;
52}
53
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000054IRForTarget::~IRForTarget()
55{
56}
57
Sean Callananf5857a02010-07-31 01:32:05 +000058static bool isObjCSelectorRef(Value *V)
59{
60 GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
61
62 if (!GV || !GV->hasName() || !GV->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_"))
63 return false;
64
65 return true;
66}
67
68bool
69IRForTarget::RewriteObjCSelector(Instruction* selector_load,
70 Module &M)
71{
72 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
73
74 LoadInst *load = dyn_cast<LoadInst>(selector_load);
75
76 if (!load)
77 return false;
78
79 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as
80 //
81 // %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*>
82 // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
83 //
84 // where %obj is the object pointer and %tmp is the selector.
85 //
86 // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_METH_VAR_NAME_".
87 // @"\01L_OBJC_METH_VAR_NAME_" contains the string.
88
89 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
90
91 GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
92
93 if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
94 return false;
95
96 Constant *osr_initializer = _objc_selector_references_->getInitializer();
97
98 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
99
100 if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
101 return false;
102
103 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
104
105 if (!osr_initializer_base)
106 return false;
107
108 // Find the string's initializer (a ConstantArray) and get the string from it
109
110 GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
111
112 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
113 return false;
114
115 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
116
117 ConstantArray *omvn_initializer_array = dyn_cast<ConstantArray>(omvn_initializer);
118
119 if (!omvn_initializer_array->isString())
120 return false;
121
122 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
123
124 if (log)
125 log->Printf("Found Objective-C selector reference %s", omvn_initializer_string.c_str());
126
127 // Construct a call to sel_registerName
128
129 if (!m_sel_registerName)
130 {
131 uint64_t srN_addr;
132
133 if (!m_decl_map->GetFunctionAddress("sel_registerName", srN_addr))
134 return false;
135
136 // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
137
138 // The below code would be "more correct," but in actuality what's required is uint8_t*
139 //Type *sel_type = StructType::get(M.getContext());
140 //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
141 const Type *sel_ptr_type = Type::getInt8PtrTy(M.getContext());
142
143 std::vector <const Type *> srN_arg_types;
144 srN_arg_types.push_back(Type::getInt8PtrTy(M.getContext()));
145 llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
146
147 // Build the constant containing the pointer to the function
148 const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(),
149 (M.getPointerSize() == Module::Pointer64) ? 64 : 32);
150 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
151 Constant *srN_addr_int = ConstantInt::get(intptr_ty, srN_addr, false);
152 m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
153 }
154
155 SmallVector <Value*, 1> srN_arguments;
156
157 Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(M.getContext()));
158
159 srN_arguments.push_back(omvn_pointer);
160
161 CallInst *srN_call = CallInst::Create(m_sel_registerName,
162 srN_arguments.begin(),
163 srN_arguments.end(),
164 "srN",
165 selector_load);
166
167 // Replace the load with the call in all users
168
169 selector_load->replaceAllUsesWith(srN_call);
170
171 selector_load->eraseFromParent();
172
173 return true;
174}
175
176bool
177IRForTarget::rewriteObjCSelectors(Module &M,
178 BasicBlock &BB)
179{
180 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
181
182 BasicBlock::iterator ii;
183
184 typedef SmallVector <Instruction*, 2> InstrList;
185 typedef InstrList::iterator InstrIterator;
186
187 InstrList selector_loads;
188
189 for (ii = BB.begin();
190 ii != BB.end();
191 ++ii)
192 {
193 Instruction &inst = *ii;
194
195 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
196 if (isObjCSelectorRef(load->getPointerOperand()))
197 selector_loads.push_back(&inst);
198 }
199
200 InstrIterator iter;
201
202 for (iter = selector_loads.begin();
203 iter != selector_loads.end();
204 ++iter)
205 {
206 if (!RewriteObjCSelector(*iter, M))
207 {
208 if(log)
209 log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
210 return false;
211 }
212 }
213
214 return true;
215}
216
Sean Callanana48fe162010-08-11 03:57:18 +0000217bool
218IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc,
219 llvm::Module &M)
220{
221 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
222
223 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
224
225 if (!alloc_md || !alloc_md->getNumOperands())
226 return false;
227
228 ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0));
229
230 if (!constant_int)
231 return false;
232
233 // We attempt to register this as a new persistent variable with the DeclMap.
234
235 uintptr_t ptr = constant_int->getZExtValue();
236
237 clang::NamedDecl *decl = reinterpret_cast<clang::NamedDecl *>(ptr);
238
239 if (!m_decl_map->AddPersistentVariable(decl))
240 return false;
241
242 GlobalVariable *persistent_global = new GlobalVariable(M,
243 alloc->getType()->getElementType(),
244 false, /* not constant */
245 GlobalValue::ExternalLinkage,
246 NULL, /* no initializer */
247 alloc->getName().str().c_str());
248
249 // What we're going to do here is make believe this was a regular old external
250 // variable. That means we need to make the metadata valid.
251
252 NamedMDNode *named_metadata = M.getNamedMetadata("clang.global.decl.ptrs");
253
254 llvm::Value* values[2];
255 values[0] = persistent_global;
256 values[1] = constant_int;
257
258 MDNode *persistent_global_md = MDNode::get(M.getContext(), values, 2);
259 named_metadata->addOperand(persistent_global_md);
260
261 alloc->replaceAllUsesWith(persistent_global);
262 alloc->eraseFromParent();
263
264 return true;
265}
266
267bool
268IRForTarget::rewritePersistentAllocs(llvm::Module &M,
269 llvm::BasicBlock &BB)
270{
271 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
272
273 BasicBlock::iterator ii;
274
275 typedef SmallVector <Instruction*, 2> InstrList;
276 typedef InstrList::iterator InstrIterator;
277
278 InstrList pvar_allocs;
279
280 for (ii = BB.begin();
281 ii != BB.end();
282 ++ii)
283 {
284 Instruction &inst = *ii;
285
286 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
287 if (alloc->getName().startswith("$"))
288 pvar_allocs.push_back(alloc);
289 }
290
291 InstrIterator iter;
292
293 for (iter = pvar_allocs.begin();
294 iter != pvar_allocs.end();
295 ++iter)
296 {
297 if (!RewritePersistentAlloc(*iter, M))
298 {
299 if(log)
300 log->PutCString("Couldn't rewrite the creation of a persistent variable");
301 return false;
302 }
303 }
304
305 return true;
306}
307
Sean Callanan8bce6652010-07-13 21:41:46 +0000308static clang::NamedDecl *
Sean Callanan02fbafa2010-07-27 21:39:39 +0000309DeclForGlobalValue(Module &module,
310 GlobalValue *global_value)
Sean Callanan8bce6652010-07-13 21:41:46 +0000311{
312 NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs");
313
314 if (!named_metadata)
315 return NULL;
316
317 unsigned num_nodes = named_metadata->getNumOperands();
318 unsigned node_index;
319
320 for (node_index = 0;
321 node_index < num_nodes;
322 ++node_index)
323 {
324 MDNode *metadata_node = named_metadata->getOperand(node_index);
325
326 if (!metadata_node)
327 return NULL;
328
329 if (metadata_node->getNumOperands() != 2)
Sean Callanana48fe162010-08-11 03:57:18 +0000330 continue;
Sean Callanan8bce6652010-07-13 21:41:46 +0000331
332 if (metadata_node->getOperand(0) != global_value)
333 continue;
334
335 ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
336
337 if (!constant_int)
338 return NULL;
339
340 uintptr_t ptr = constant_int->getZExtValue();
341
342 return reinterpret_cast<clang::NamedDecl *>(ptr);
343 }
344
345 return NULL;
346}
347
348bool
349IRForTarget::MaybeHandleVariable(Module &M,
Sean Callanan02fbafa2010-07-27 21:39:39 +0000350 Value *V,
Sean Callanan8bce6652010-07-13 21:41:46 +0000351 bool Store)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000352{
Sean Callananf5857a02010-07-31 01:32:05 +0000353 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
354
Sean Callananbc2928a2010-08-03 00:23:29 +0000355 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(V))
356 {
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000357 switch (constant_expr->getOpcode())
Sean Callananbc2928a2010-08-03 00:23:29 +0000358 {
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000359 default:
360 break;
361 case Instruction::GetElementPtr:
362 case Instruction::BitCast:
Sean Callananbc2928a2010-08-03 00:23:29 +0000363 Value *s = constant_expr->getOperand(0);
364 MaybeHandleVariable(M, s, Store);
365 }
366 }
Sean Callanan8bce6652010-07-13 21:41:46 +0000367 if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
Sean Callananf5857a02010-07-31 01:32:05 +0000368 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000369 clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000370
Sean Callananf5857a02010-07-31 01:32:05 +0000371 if (!named_decl)
372 {
373 if (isObjCSelectorRef(V))
374 return true;
375
376 if (log)
377 log->Printf("Found global variable %s without metadata", global_variable->getName().str().c_str());
378 return false;
379 }
380
Sean Callanan810f22d2010-07-16 00:09:46 +0000381 std::string name = named_decl->getName().str();
382
383 void *qual_type = NULL;
Sean Callananf328c9f2010-07-20 23:31:16 +0000384 clang::ASTContext *ast_context = NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000385
386 if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
Sean Callananf328c9f2010-07-20 23:31:16 +0000387 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000388 qual_type = value_decl->getType().getAsOpaquePtr();
Sean Callananf328c9f2010-07-20 23:31:16 +0000389 ast_context = &value_decl->getASTContext();
390 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000391 else
Sean Callananf328c9f2010-07-20 23:31:16 +0000392 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000393 return false;
Sean Callananf328c9f2010-07-20 23:31:16 +0000394 }
395
Sean Callanan02fbafa2010-07-27 21:39:39 +0000396 const Type *value_type = global_variable->getType();
Sean Callanan8bce6652010-07-13 21:41:46 +0000397
398 size_t value_size = m_target_data->getTypeStoreSize(value_type);
399 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
400
Sean Callananba992c52010-07-27 02:07:53 +0000401 if (named_decl && !m_decl_map->AddValueToStruct(V,
402 named_decl,
403 name,
404 qual_type,
405 ast_context,
406 value_size,
407 value_alignment))
Sean Callanan8bce6652010-07-13 21:41:46 +0000408 return false;
409 }
410
411 return true;
412}
413
414bool
Sean Callananba992c52010-07-27 02:07:53 +0000415IRForTarget::MaybeHandleCall(Module &M,
416 CallInst *C)
417{
418 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
419
Sean Callanan02fbafa2010-07-27 21:39:39 +0000420 Function *fun = C->getCalledFunction();
Sean Callananba992c52010-07-27 02:07:53 +0000421
422 if (fun == NULL)
423 return true;
424
425 clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun);
Sean Callanan02fbafa2010-07-27 21:39:39 +0000426 uint64_t fun_addr;
Sean Callananf5857a02010-07-31 01:32:05 +0000427 Value **fun_value_ptr = NULL;
Sean Callananba992c52010-07-27 02:07:53 +0000428
Sean Callananf5857a02010-07-31 01:32:05 +0000429 if (fun_decl)
Sean Callananba992c52010-07-27 02:07:53 +0000430 {
Sean Callananf5857a02010-07-31 01:32:05 +0000431 if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr))
432 {
433 if (log)
434 log->Printf("Function %s had no address", fun_decl->getNameAsCString());
435 return false;
436 }
437 }
438 else
439 {
440 if (!m_decl_map->GetFunctionAddress(fun->getName().str().c_str(), fun_addr))
441 {
442 if (log)
443 log->Printf("Metadataless function %s had no address", fun->getName().str().c_str());
444 return false;
445 }
Sean Callananba992c52010-07-27 02:07:53 +0000446 }
447
448 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000449 log->Printf("Found %s at %llx", fun->getName().str().c_str(), fun_addr);
Sean Callananba992c52010-07-27 02:07:53 +0000450
Sean Callananf5857a02010-07-31 01:32:05 +0000451 Value *fun_addr_ptr;
452
453 if (!fun_value_ptr || !*fun_value_ptr)
Sean Callanan02fbafa2010-07-27 21:39:39 +0000454 {
455 std::vector<const Type*> params;
456
457 const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(),
458 (M.getPointerSize() == Module::Pointer64) ? 64 : 32);
459
460 FunctionType *fun_ty = FunctionType::get(intptr_ty, params, true);
461 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
462 Constant *fun_addr_int = ConstantInt::get(intptr_ty, fun_addr, false);
Sean Callananf5857a02010-07-31 01:32:05 +0000463 fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
464
465 if (fun_value_ptr)
466 *fun_value_ptr = fun_addr_ptr;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000467 }
Sean Callananf5857a02010-07-31 01:32:05 +0000468
469 if (fun_value_ptr)
470 fun_addr_ptr = *fun_value_ptr;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000471
Sean Callananf5857a02010-07-31 01:32:05 +0000472 C->setCalledFunction(fun_addr_ptr);
Sean Callanan02fbafa2010-07-27 21:39:39 +0000473
Sean Callananba992c52010-07-27 02:07:53 +0000474 return true;
475}
476
477bool
Sean Callananf5857a02010-07-31 01:32:05 +0000478IRForTarget::resolveExternals(Module &M, BasicBlock &BB)
Sean Callanan8bce6652010-07-13 21:41:46 +0000479{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000480 /////////////////////////////////////////////////////////////////////////
481 // Prepare the current basic block for execution in the remote process
482 //
483
Sean Callanan02fbafa2010-07-27 21:39:39 +0000484 BasicBlock::iterator ii;
Sean Callanan8bce6652010-07-13 21:41:46 +0000485
486 for (ii = BB.begin();
487 ii != BB.end();
488 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000489 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000490 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000491
Sean Callanan8bce6652010-07-13 21:41:46 +0000492 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000493 if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
Sean Callanan8bce6652010-07-13 21:41:46 +0000494 return false;
Sean Callananf5857a02010-07-31 01:32:05 +0000495
Sean Callanan8bce6652010-07-13 21:41:46 +0000496 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
Sean Callananba992c52010-07-27 02:07:53 +0000497 if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
498 return false;
499
500 if (CallInst *call = dyn_cast<CallInst>(&inst))
501 if (!MaybeHandleCall(M, call))
Sean Callanan8bce6652010-07-13 21:41:46 +0000502 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000503 }
504
505 return true;
506}
507
Sean Callanan02fbafa2010-07-27 21:39:39 +0000508static bool isGuardVariableRef(Value *V)
Sean Callanan45839272010-07-24 01:37:44 +0000509{
510 ConstantExpr *C = dyn_cast<ConstantExpr>(V);
511
512 if (!C || C->getOpcode() != Instruction::BitCast)
513 return false;
514
515 GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
516
517 if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
518 return false;
519
520 return true;
521}
522
523static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
524{
525 Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
526
527 Value::use_iterator ui;
528
529 for (ui = guard_load->use_begin();
530 ui != guard_load->use_end();
531 ++ui)
Sean Callananb5b749c2010-07-27 01:17:28 +0000532 {
Greg Clayton6e713402010-07-30 20:30:44 +0000533 if (isa<Constant>(*ui))
Sean Callananb5b749c2010-07-27 01:17:28 +0000534 {
535 // do nothing for the moment
536 }
537 else
538 {
539 ui->replaceUsesOfWith(guard_load, zero);
540 }
541 }
Sean Callanan45839272010-07-24 01:37:44 +0000542
543 guard_load->eraseFromParent();
544}
545
546static void ExciseGuardStore(Instruction* guard_store)
547{
548 guard_store->eraseFromParent();
549}
550
551bool
552IRForTarget::removeGuards(Module &M, BasicBlock &BB)
553{
554 ///////////////////////////////////////////////////////
555 // Eliminate any reference to guard variables found.
556 //
557
Sean Callanan02fbafa2010-07-27 21:39:39 +0000558 BasicBlock::iterator ii;
Sean Callanan45839272010-07-24 01:37:44 +0000559
Sean Callanan02fbafa2010-07-27 21:39:39 +0000560 typedef SmallVector <Instruction*, 2> InstrList;
Sean Callanan45839272010-07-24 01:37:44 +0000561 typedef InstrList::iterator InstrIterator;
562
563 InstrList guard_loads;
564 InstrList guard_stores;
565
566 for (ii = BB.begin();
567 ii != BB.end();
568 ++ii)
569 {
570 Instruction &inst = *ii;
571
572 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
573 if (isGuardVariableRef(load->getPointerOperand()))
574 guard_loads.push_back(&inst);
575
576 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
577 if (isGuardVariableRef(store->getPointerOperand()))
578 guard_stores.push_back(&inst);
579 }
580
581 InstrIterator iter;
582
583 for (iter = guard_loads.begin();
584 iter != guard_loads.end();
585 ++iter)
586 TurnGuardLoadIntoZero(*iter, M);
587
588 for (iter = guard_stores.begin();
589 iter != guard_stores.end();
590 ++iter)
591 ExciseGuardStore(*iter);
592
593 return true;
594}
595
Sean Callananbafd6852010-07-14 23:40:29 +0000596// UnfoldConstant operates on a constant [C] which has just been replaced with a value
597// [new_value]. We assume that new_value has been properly placed early in the function,
598// most likely somewhere in front of the first instruction in the entry basic block
599// [first_entry_instruction].
600//
601// UnfoldConstant reads through the uses of C and replaces C in those uses with new_value.
602// Where those uses are constants, the function generates new instructions to compute the
603// result of the new, non-constant expression and places them before first_entry_instruction.
604// These instructions replace the constant uses, so UnfoldConstant calls itself recursively
605// for those.
606
607static bool
Sean Callanan02fbafa2010-07-27 21:39:39 +0000608UnfoldConstant(Constant *C, Value *new_value, Instruction *first_entry_instruction)
Sean Callananbafd6852010-07-14 23:40:29 +0000609{
610 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
611
612 Value::use_iterator ui;
613
Sean Callanana48fe162010-08-11 03:57:18 +0000614 SmallVector<User*, 16> users;
615
616 // We do this because the use list might change, invalidating our iterator.
617 // Much better to keep a work list ourselves.
Sean Callananbafd6852010-07-14 23:40:29 +0000618 for (ui = C->use_begin();
619 ui != C->use_end();
620 ++ui)
Sean Callanana48fe162010-08-11 03:57:18 +0000621 users.push_back(*ui);
Sean Callananbafd6852010-07-14 23:40:29 +0000622
Sean Callanana48fe162010-08-11 03:57:18 +0000623 for (int i = 0;
624 i < users.size();
625 ++i)
626 {
627 User *user = users[i];
628
Sean Callananbafd6852010-07-14 23:40:29 +0000629 if (Constant *constant = dyn_cast<Constant>(user))
630 {
631 // synthesize a new non-constant equivalent of the constant
632
633 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
634 {
635 switch (constant_expr->getOpcode())
636 {
637 default:
638 if (log)
639 log->Printf("Unhandled constant expression type: %s", PrintValue(constant_expr).c_str());
640 return false;
641 case Instruction::BitCast:
642 {
643 // UnaryExpr
644 // OperandList[0] is value
645
646 Value *s = constant_expr->getOperand(0);
647
648 if (s == C)
649 s = new_value;
650
651 BitCastInst *bit_cast(new BitCastInst(s, C->getType(), "", first_entry_instruction));
652
653 UnfoldConstant(constant_expr, bit_cast, first_entry_instruction);
654 }
655 break;
656 case Instruction::GetElementPtr:
657 {
658 // GetElementPtrConstantExpr
659 // OperandList[0] is base
660 // OperandList[1]... are indices
661
662 Value *ptr = constant_expr->getOperand(0);
663
664 if (ptr == C)
665 ptr = new_value;
666
667 SmallVector<Value*, 16> indices;
668
669 unsigned operand_index;
670 unsigned num_operands = constant_expr->getNumOperands();
671
672 for (operand_index = 1;
673 operand_index < num_operands;
674 ++operand_index)
675 {
676 Value *operand = constant_expr->getOperand(operand_index);
677
678 if (operand == C)
679 operand = new_value;
680
681 indices.push_back(operand);
682 }
683
684 GetElementPtrInst *get_element_ptr(GetElementPtrInst::Create(ptr, indices.begin(), indices.end(), "", first_entry_instruction));
685
686 UnfoldConstant(constant_expr, get_element_ptr, first_entry_instruction);
687 }
688 break;
689 }
690 }
691 else
692 {
693 if (log)
694 log->Printf("Unhandled constant type: %s", PrintValue(constant).c_str());
695 return false;
696 }
697 }
698 else
699 {
700 // simple fall-through case for non-constants
701 user->replaceUsesOfWith(C, new_value);
702 }
703 }
704
705 return true;
706}
707
Sean Callanan8bce6652010-07-13 21:41:46 +0000708bool
Sean Callananf5857a02010-07-31 01:32:05 +0000709IRForTarget::replaceVariables(Module &M, Function &F)
Sean Callanan8bce6652010-07-13 21:41:46 +0000710{
711 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
712
713 m_decl_map->DoStructLayout();
714
715 if (log)
716 log->Printf("Element arrangement:");
717
718 uint32_t num_elements;
719 uint32_t element_index;
720
721 size_t size;
722 off_t alignment;
723
724 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
725 return false;
726
Sean Callananf5857a02010-07-31 01:32:05 +0000727 Function::arg_iterator iter(F.getArgumentList().begin());
Sean Callanan8bce6652010-07-13 21:41:46 +0000728
Sean Callananf5857a02010-07-31 01:32:05 +0000729 if (iter == F.getArgumentList().end())
Sean Callanan8bce6652010-07-13 21:41:46 +0000730 return false;
731
Sean Callanan02fbafa2010-07-27 21:39:39 +0000732 Argument *argument = iter;
Sean Callanan8bce6652010-07-13 21:41:46 +0000733
734 if (!argument->getName().equals("___clang_arg"))
735 return false;
736
737 if (log)
738 log->Printf("Arg: %s", PrintValue(argument).c_str());
739
Sean Callananf5857a02010-07-31 01:32:05 +0000740 BasicBlock &entry_block(F.getEntryBlock());
Sean Callanan02fbafa2010-07-27 21:39:39 +0000741 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sean Callanan8bce6652010-07-13 21:41:46 +0000742
743 if (!first_entry_instruction)
744 return false;
745
746 LLVMContext &context(M.getContext());
747 const IntegerType *offset_type(Type::getInt32Ty(context));
748
749 if (!offset_type)
750 return false;
751
752 for (element_index = 0; element_index < num_elements; ++element_index)
753 {
754 const clang::NamedDecl *decl;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000755 Value *value;
Sean Callanan8bce6652010-07-13 21:41:46 +0000756 off_t offset;
757
758 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
759 return false;
760
761 if (log)
762 log->Printf(" %s (%s) placed at %d",
763 decl->getIdentifier()->getNameStart(),
764 PrintValue(value, true).c_str(),
765 offset);
766
767 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
768 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
769 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
770
Sean Callananbafd6852010-07-14 23:40:29 +0000771 if (Constant *constant = dyn_cast<Constant>(value))
772 UnfoldConstant(constant, bit_cast, first_entry_instruction);
773 else
774 value->replaceAllUsesWith(bit_cast);
Sean Callanan8bce6652010-07-13 21:41:46 +0000775 }
776
777 if (log)
778 log->Printf("Total structure [align %d, size %d]", alignment, size);
779
780 return true;
781}
782
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000783bool
784IRForTarget::runOnModule(Module &M)
785{
786 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
787
Sean Callanan02fbafa2010-07-27 21:39:39 +0000788 Function* function = M.getFunction(StringRef("___clang_expr"));
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000789
790 if (!function)
791 {
792 if (log)
793 log->Printf("Couldn't find ___clang_expr() in the module");
794
795 return false;
796 }
797
Sean Callanan02fbafa2010-07-27 21:39:39 +0000798 Function::iterator bbi;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000799
Sean Callananf5857a02010-07-31 01:32:05 +0000800 //////////////////////////////////
801 // Run basic-block level passes
802 //
803
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000804 for (bbi = function->begin();
805 bbi != function->end();
806 ++bbi)
807 {
Sean Callanana48fe162010-08-11 03:57:18 +0000808 if (!rewritePersistentAllocs(M, *bbi))
Sean Callananf5857a02010-07-31 01:32:05 +0000809 return false;
810
Sean Callanana48fe162010-08-11 03:57:18 +0000811 if (!rewriteObjCSelectors(M, *bbi))
812 return false;
813
Sean Callananf5857a02010-07-31 01:32:05 +0000814 if (!resolveExternals(M, *bbi))
Sean Callanan8bce6652010-07-13 21:41:46 +0000815 return false;
Sean Callanan45839272010-07-24 01:37:44 +0000816
817 if (!removeGuards(M, *bbi))
818 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000819 }
820
Sean Callanan8bce6652010-07-13 21:41:46 +0000821 if (log)
822 {
Sean Callanan321fe9e2010-07-28 01:00:59 +0000823 std::string s;
824 raw_string_ostream oss(s);
Sean Callanan8bce6652010-07-13 21:41:46 +0000825
Sean Callanan321fe9e2010-07-28 01:00:59 +0000826 M.print(oss, NULL);
827
828 oss.flush();
829
830 log->Printf("Module after preparing for execution: \n%s", s.c_str());
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000831 }
832
Sean Callanana48fe162010-08-11 03:57:18 +0000833 ///////////////////////////////
834 // Run function-level passes
835 //
836
837 if (!replaceVariables(M, *function))
838 return false;
839
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000840 return true;
841}
842
843void
844IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000845 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000846{
847}
848
849PassManagerType
850IRForTarget::getPotentialPassManagerType() const
851{
852 return PMT_ModulePassManager;
853}