blob: 8876109448e1e146260caeebc5eefe29e26f13dd [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{
89 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8bce6652010-07-13 21:41:46 +000090
91 if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
92 {
93 clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
Sean Callanan5cf4a1c2010-07-03 01:35:46 +000094
Sean Callanan8bce6652010-07-13 21:41:46 +000095 const llvm::Type *value_type = global_variable->getType();
96
97 size_t value_size = m_target_data->getTypeStoreSize(value_type);
98 off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
99
100 if (named_decl && !DM->AddValueToStruct(V, named_decl, value_size, value_alignment))
101 return false;
102 }
103
104 return true;
105}
106
107bool
108IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
109{
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000110 /////////////////////////////////////////////////////////////////////////
111 // Prepare the current basic block for execution in the remote process
112 //
113
Sean Callanan8bce6652010-07-13 21:41:46 +0000114 llvm::BasicBlock::iterator ii;
115
116 for (ii = BB.begin();
117 ii != BB.end();
118 ++ii)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000119 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000120 Instruction &inst = *ii;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000121
Sean Callanan8bce6652010-07-13 21:41:46 +0000122 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
123 if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false))
124 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000125
Sean Callanan8bce6652010-07-13 21:41:46 +0000126 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
127 if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false))
128 return false;
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000129 }
130
131 return true;
132}
133
Sean Callanan8bce6652010-07-13 21:41:46 +0000134static std::string PrintValue(llvm::Value *V, bool truncate = false)
135{
136 std::string s;
137 raw_string_ostream rso(s);
138 V->print(rso);
139 rso.flush();
140 if (truncate)
141 s.resize(s.length() - 1);
142 return s;
143}
144
145bool
146IRForTarget::replaceVariables(Module &M, Function *F)
147{
148 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
149
150 m_decl_map->DoStructLayout();
151
152 if (log)
153 log->Printf("Element arrangement:");
154
155 uint32_t num_elements;
156 uint32_t element_index;
157
158 size_t size;
159 off_t alignment;
160
161 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
162 return false;
163
164 Function::arg_iterator iter(F->getArgumentList().begin());
165
166 if (iter == F->getArgumentList().end())
167 return false;
168
169 llvm::Argument *argument = iter;
170
171 if (!argument->getName().equals("___clang_arg"))
172 return false;
173
174 if (log)
175 log->Printf("Arg: %s", PrintValue(argument).c_str());
176
177 llvm::BasicBlock &entry_block(F->getEntryBlock());
178 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
179
180 if (!first_entry_instruction)
181 return false;
182
183 LLVMContext &context(M.getContext());
184 const IntegerType *offset_type(Type::getInt32Ty(context));
185
186 if (!offset_type)
187 return false;
188
189 for (element_index = 0; element_index < num_elements; ++element_index)
190 {
191 const clang::NamedDecl *decl;
192 llvm::Value *value;
193 off_t offset;
194
195 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
196 return false;
197
198 if (log)
199 log->Printf(" %s (%s) placed at %d",
200 decl->getIdentifier()->getNameStart(),
201 PrintValue(value, true).c_str(),
202 offset);
203
204 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
205 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
206 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
207
208 value->replaceAllUsesWith(bit_cast);
209 }
210
211 if (log)
212 log->Printf("Total structure [align %d, size %d]", alignment, size);
213
214 return true;
215}
216
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000217bool
218IRForTarget::runOnModule(Module &M)
219{
220 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
221
222 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
223
224 if (!function)
225 {
226 if (log)
227 log->Printf("Couldn't find ___clang_expr() in the module");
228
229 return false;
230 }
231
232 llvm::Function::iterator bbi;
233
234 for (bbi = function->begin();
235 bbi != function->end();
236 ++bbi)
237 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000238 if (!runOnBasicBlock(M, *bbi))
239 return false;
240 }
241
242 if (!replaceVariables(M, function))
243 return false;
244
245 if (log)
246 {
247 for (bbi = function->begin();
248 bbi != function->end();
249 ++bbi)
250 {
251 log->Printf("Rewrote basic block %s for running: \n%s",
252 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
253 PrintValue(bbi).c_str());
254 }
255
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000256 }
257
258 return true;
259}
260
261void
262IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000263 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000264{
265}
266
267PassManagerType
268IRForTarget::getPotentialPassManagerType() const
269{
270 return PMT_ModulePassManager;
271}