blob: fc8b0393bc2854cac8f36605decd6a066b61e375 [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 Callanan8bce6652010-07-13 21:41:46 +0000132static std::string PrintValue(llvm::Value *V, bool truncate = false)
133{
134 std::string s;
135 raw_string_ostream rso(s);
136 V->print(rso);
137 rso.flush();
138 if (truncate)
139 s.resize(s.length() - 1);
140 return s;
141}
142
143bool
144IRForTarget::replaceVariables(Module &M, Function *F)
145{
146 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
147
148 m_decl_map->DoStructLayout();
149
150 if (log)
151 log->Printf("Element arrangement:");
152
153 uint32_t num_elements;
154 uint32_t element_index;
155
156 size_t size;
157 off_t alignment;
158
159 if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
160 return false;
161
162 Function::arg_iterator iter(F->getArgumentList().begin());
163
164 if (iter == F->getArgumentList().end())
165 return false;
166
167 llvm::Argument *argument = iter;
168
169 if (!argument->getName().equals("___clang_arg"))
170 return false;
171
172 if (log)
173 log->Printf("Arg: %s", PrintValue(argument).c_str());
174
175 llvm::BasicBlock &entry_block(F->getEntryBlock());
176 llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
177
178 if (!first_entry_instruction)
179 return false;
180
181 LLVMContext &context(M.getContext());
182 const IntegerType *offset_type(Type::getInt32Ty(context));
183
184 if (!offset_type)
185 return false;
186
187 for (element_index = 0; element_index < num_elements; ++element_index)
188 {
189 const clang::NamedDecl *decl;
190 llvm::Value *value;
191 off_t offset;
192
193 if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
194 return false;
195
196 if (log)
197 log->Printf(" %s (%s) placed at %d",
198 decl->getIdentifier()->getNameStart(),
199 PrintValue(value, true).c_str(),
200 offset);
201
202 ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
203 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
204 BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
205
206 value->replaceAllUsesWith(bit_cast);
207 }
208
209 if (log)
210 log->Printf("Total structure [align %d, size %d]", alignment, size);
211
212 return true;
213}
214
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000215bool
216IRForTarget::runOnModule(Module &M)
217{
218 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
219
220 llvm::Function* function = M.getFunction(StringRef("___clang_expr"));
221
222 if (!function)
223 {
224 if (log)
225 log->Printf("Couldn't find ___clang_expr() in the module");
226
227 return false;
228 }
229
230 llvm::Function::iterator bbi;
231
232 for (bbi = function->begin();
233 bbi != function->end();
234 ++bbi)
235 {
Sean Callanan8bce6652010-07-13 21:41:46 +0000236 if (!runOnBasicBlock(M, *bbi))
237 return false;
238 }
239
240 if (!replaceVariables(M, function))
241 return false;
242
243 if (log)
244 {
245 for (bbi = function->begin();
246 bbi != function->end();
247 ++bbi)
248 {
249 log->Printf("Rewrote basic block %s for running: \n%s",
250 bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
251 PrintValue(bbi).c_str());
252 }
253
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000254 }
255
256 return true;
257}
258
259void
260IRForTarget::assignPassManager(PMStack &PMS,
Sean Callanan8bce6652010-07-13 21:41:46 +0000261 PassManagerType T)
Sean Callanan5cf4a1c2010-07-03 01:35:46 +0000262{
263}
264
265PassManagerType
266IRForTarget::getPotentialPassManagerType() const
267{
268 return PMT_ModulePassManager;
269}