Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: lib/Transforms/NaCl/ExpandTls.cpp

Issue 1151093004: Changes from 3.7 merge to files not in upstream (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- ExpandTls.cpp - Convert TLS variables to a concrete layout----------===// 1 //===- ExpandTls.cpp - Convert TLS variables to a concrete layout----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This pass expands out uses of thread-local (TLS) variables into 10 // This pass expands out uses of thread-local (TLS) variables into
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 unsigned Alignment = State->DL.getPreferredAlignment(TlsVar); 109 unsigned Alignment = State->DL.getPreferredAlignment(TlsVar);
110 padToAlignment(State, FieldTypes, FieldValues, Alignment); 110 padToAlignment(State, FieldTypes, FieldValues, Alignment);
111 111
112 FieldTypes->push_back(TlsVar->getType()->getElementType()); 112 FieldTypes->push_back(TlsVar->getType()->getElementType());
113 if (FieldValues) 113 if (FieldValues)
114 FieldValues->push_back(TlsVar->getInitializer()); 114 FieldValues->push_back(TlsVar->getInitializer());
115 State->Offset += 115 State->Offset +=
116 State->DL.getTypeAllocSize(TlsVar->getType()->getElementType()); 116 State->DL.getTypeAllocSize(TlsVar->getType()->getElementType());
117 } 117 }
118 118
119 static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) { 119 static StructType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) {
120 std::vector<Type*> FieldBssTypes; 120 std::vector<Type*> FieldBssTypes;
121 std::vector<Type*> FieldInitTypes; 121 std::vector<Type*> FieldInitTypes;
122 std::vector<Constant*> FieldInitValues; 122 std::vector<Constant*> FieldInitValues;
123 PassState State(&M); 123 PassState State(&M);
124 124
125 for (Module::global_iterator GV = M.global_begin(); 125 for (Module::global_iterator GV = M.global_begin();
126 GV != M.global_end(); 126 GV != M.global_end();
127 ++GV) { 127 ++GV) {
128 if (GV->isThreadLocal()) { 128 if (GV->isThreadLocal()) {
129 if (!GV->hasInitializer()) { 129 if (!GV->hasInitializer()) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 const char *StartSymbol = "__tls_template_start"; 196 const char *StartSymbol = "__tls_template_start";
197 Constant *TemplateData = ConstantStruct::get(InitTemplateType, 197 Constant *TemplateData = ConstantStruct::get(InitTemplateType,
198 FieldInitValues); 198 FieldInitValues);
199 GlobalVariable *TemplateDataVar = 199 GlobalVariable *TemplateDataVar =
200 new GlobalVariable(M, InitTemplateType, /*isConstant=*/true, 200 new GlobalVariable(M, InitTemplateType, /*isConstant=*/true,
201 GlobalValue::InternalLinkage, TemplateData); 201 GlobalValue::InternalLinkage, TemplateData);
202 setGlobalVariableValue(M, StartSymbol, TemplateDataVar); 202 setGlobalVariableValue(M, StartSymbol, TemplateDataVar);
203 TemplateDataVar->setName(StartSymbol); 203 TemplateDataVar->setName(StartSymbol);
204 204
205 Constant *TdataEnd = ConstantExpr::getGetElementPtr( 205 Constant *TdataEnd = ConstantExpr::getGetElementPtr(
206 InitTemplateType,
206 TemplateDataVar, 207 TemplateDataVar,
207 ConstantInt::get(M.getContext(), APInt(32, 1))); 208 ConstantInt::get(M.getContext(), APInt(32, 1)));
208 setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd); 209 setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd);
209 210
210 Constant *TotalEnd = ConstantExpr::getGetElementPtr( 211 Constant *TotalEnd = ConstantExpr::getGetElementPtr(
212 TemplateType,
211 ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType), 213 ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType),
212 ConstantInt::get(M.getContext(), APInt(32, 1))); 214 ConstantInt::get(M.getContext(), APInt(32, 1)));
213 setGlobalVariableValue(M, "__tls_template_end", TotalEnd); 215 setGlobalVariableValue(M, "__tls_template_end", TotalEnd);
214 216
215 const char *AlignmentSymbol = "__tls_template_alignment"; 217 const char *AlignmentSymbol = "__tls_template_alignment";
216 Type *i32 = Type::getInt32Ty(M.getContext()); 218 Type *i32 = Type::getInt32Ty(M.getContext());
217 GlobalVariable *AlignmentVar = new GlobalVariable( 219 GlobalVariable *AlignmentVar = new GlobalVariable(
218 M, i32, /*isConstant=*/true, 220 M, i32, /*isConstant=*/true,
219 GlobalValue::InternalLinkage, 221 GlobalValue::InternalLinkage,
220 ConstantInt::get(M.getContext(), APInt(32, State.Alignment))); 222 ConstantInt::get(M.getContext(), APInt(32, State.Alignment)));
221 setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar); 223 setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar);
222 AlignmentVar->setName(AlignmentSymbol); 224 AlignmentVar->setName(AlignmentSymbol);
223 225
224 return TemplatePtrType; 226 return TemplateType;
225 } 227 }
226 228
227 static void rewriteTlsVars(Module &M, std::vector<VarInfo> *TlsVars, 229 static void rewriteTlsVars(Module &M, std::vector<VarInfo> *TlsVars,
228 PointerType *TemplatePtrType) { 230 StructType *TemplateType) {
229 // Set up the intrinsic that reads the thread pointer. 231 // Set up the intrinsic that reads the thread pointer.
230 Function *ReadTpFunc = Intrinsic::getDeclaration(&M, Intrinsic::nacl_read_tp); 232 Function *ReadTpFunc = Intrinsic::getDeclaration(&M, Intrinsic::nacl_read_tp);
231 233
232 for (std::vector<VarInfo>::iterator VarInfo = TlsVars->begin(); 234 for (std::vector<VarInfo>::iterator VarInfo = TlsVars->begin();
233 VarInfo != TlsVars->end(); 235 VarInfo != TlsVars->end();
234 ++VarInfo) { 236 ++VarInfo) {
235 GlobalVariable *Var = VarInfo->TlsVar; 237 GlobalVariable *Var = VarInfo->TlsVar;
236 while (Var->hasNUsesOrMore(1)) { 238 while (Var->hasNUsesOrMore(1)) {
237 Use *U = &*Var->use_begin(); 239 Use *U = &*Var->use_begin();
238 Instruction *InsertPt = PhiSafeInsertPt(U); 240 Instruction *InsertPt = PhiSafeInsertPt(U);
239 Value *RawThreadPtr = CallInst::Create(ReadTpFunc, "tls_raw", InsertPt); 241 Value *RawThreadPtr = CallInst::Create(ReadTpFunc, "tls_raw", InsertPt);
240 Value *TypedThreadPtr = new BitCastInst(RawThreadPtr, TemplatePtrType, 242 Value *TypedThreadPtr = new BitCastInst(
241 "tls_struct", InsertPt); 243 RawThreadPtr, TemplateType->getPointerTo(), "tls_struct", InsertPt);
242 SmallVector<Value*, 3> Indexes; 244 SmallVector<Value*, 3> Indexes;
243 // We use -1 because we use the x86-style TLS layout in which 245 // We use -1 because we use the x86-style TLS layout in which
244 // the TLS data is stored at addresses below the thread pointer. 246 // the TLS data is stored at addresses below the thread pointer.
245 // This is largely because a check in nacl_irt_thread_create() 247 // This is largely because a check in nacl_irt_thread_create()
246 // in irt/irt_thread.c requires the thread pointer to be a 248 // in irt/irt_thread.c requires the thread pointer to be a
247 // self-pointer on x86-32. 249 // self-pointer on x86-32.
248 // TODO(mseaborn): I intend to remove that check because it is 250 // TODO(mseaborn): I intend to remove that check because it is
249 // non-portable. In the mean time, we want PNaCl pexes to work 251 // non-portable. In the mean time, we want PNaCl pexes to work
250 // in older Chromium releases when translated to nexes. 252 // in older Chromium releases when translated to nexes.
251 Indexes.push_back(ConstantInt::get( 253 Indexes.push_back(ConstantInt::get(
252 M.getContext(), APInt(32, -1))); 254 M.getContext(), APInt(32, -1)));
253 Indexes.push_back(ConstantInt::get( 255 Indexes.push_back(ConstantInt::get(
254 M.getContext(), APInt(32, VarInfo->IsBss ? 1 : 0))); 256 M.getContext(), APInt(32, VarInfo->IsBss ? 1 : 0)));
255 Indexes.push_back(ConstantInt::get( 257 Indexes.push_back(ConstantInt::get(
256 M.getContext(), APInt(32, VarInfo->TemplateIndex))); 258 M.getContext(), APInt(32, VarInfo->TemplateIndex)));
257 Value *TlsField = GetElementPtrInst::Create(TypedThreadPtr, Indexes, 259 Value *TlsField = GetElementPtrInst::Create(
258 "field", InsertPt); 260 TemplateType, TypedThreadPtr, Indexes, "field", InsertPt);
259 PhiSafeReplaceUses(U, TlsField); 261 PhiSafeReplaceUses(U, TlsField);
260 } 262 }
261 VarInfo->TlsVar->eraseFromParent(); 263 VarInfo->TlsVar->eraseFromParent();
262 } 264 }
263 } 265 }
264 266
265 static void replaceFunction(Module &M, const char *Name, Value *NewFunc) { 267 static void replaceFunction(Module &M, const char *Name, Value *NewFunc) {
266 if (Function *Func = M.getFunction(Name)) { 268 if (Function *Func = M.getFunction(Name)) {
267 if (Func->hasLocalLinkage()) 269 if (Func->hasLocalLinkage())
268 return; 270 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 ReturnInst::Create(M.getContext(), Result, BB); 316 ReturnInst::Create(M.getContext(), Result, BB);
315 replaceFunction(M, "__nacl_tp_tls_offset", NewFunc); 317 replaceFunction(M, "__nacl_tp_tls_offset", NewFunc);
316 } 318 }
317 319
318 bool ExpandTls::runOnModule(Module &M) { 320 bool ExpandTls::runOnModule(Module &M) {
319 ModulePass *Pass = createExpandTlsConstantExprPass(); 321 ModulePass *Pass = createExpandTlsConstantExprPass();
320 Pass->runOnModule(M); 322 Pass->runOnModule(M);
321 delete Pass; 323 delete Pass;
322 324
323 std::vector<VarInfo> TlsVars; 325 std::vector<VarInfo> TlsVars;
324 PointerType *TemplatePtrType = buildTlsTemplate(M, &TlsVars); 326 StructType *TemplateType = buildTlsTemplate(M, &TlsVars);
325 rewriteTlsVars(M, &TlsVars, TemplatePtrType); 327 rewriteTlsVars(M, &TlsVars, TemplateType);
326 328
327 defineTlsLayoutFunctions(M); 329 defineTlsLayoutFunctions(M);
328 330
329 return true; 331 return true;
330 } 332 }
331 333
332 ModulePass *llvm::createExpandTlsPass() { 334 ModulePass *llvm::createExpandTlsPass() {
333 return new ExpandTls(); 335 return new ExpandTls();
334 } 336 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698