Chromium Code Reviews

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

Issue 1759263003: PNaCl: ExpandTls: Use C++11 range-based "for" loops (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 104 matching lines...)
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 StructType *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 (GlobalVariable &GV : M.globals()) {
126 GV != M.global_end(); 126 if (GV.isThreadLocal()) {
127 ++GV) { 127 if (!GV.hasInitializer()) {
128 if (GV->isThreadLocal()) {
129 if (!GV->hasInitializer()) {
130 // Since this is a whole-program transformation, "extern" TLS 128 // Since this is a whole-program transformation, "extern" TLS
131 // variables are not allowed at this point. 129 // variables are not allowed at this point.
132 report_fatal_error(std::string("TLS variable without an initializer: ") 130 report_fatal_error(std::string("TLS variable without an initializer: ")
133 + GV->getName()); 131 + GV.getName());
134 } 132 }
135 if (!GV->getInitializer()->isNullValue()) { 133 if (!GV.getInitializer()->isNullValue()) {
136 addVarToTlsTemplate(&State, &FieldInitTypes, 134 addVarToTlsTemplate(&State, &FieldInitTypes, &FieldInitValues, &GV);
137 &FieldInitValues, GV);
138 VarInfo Info; 135 VarInfo Info;
139 Info.TlsVar = GV; 136 Info.TlsVar = &GV;
140 Info.IsBss = false; 137 Info.IsBss = false;
141 Info.TemplateIndex = FieldInitTypes.size() - 1; 138 Info.TemplateIndex = FieldInitTypes.size() - 1;
142 TlsVars->push_back(Info); 139 TlsVars->push_back(Info);
143 } 140 }
144 } 141 }
145 } 142 }
146 // Handle zero-initialized TLS variables in a second pass, because 143 // Handle zero-initialized TLS variables in a second pass, because
147 // these should follow non-zero-initialized TLS variables. 144 // these should follow non-zero-initialized TLS variables.
148 for (Module::global_iterator GV = M.global_begin(); 145 for (GlobalVariable &GV : M.globals()) {
149 GV != M.global_end(); 146 if (GV.isThreadLocal() && GV.getInitializer()->isNullValue()) {
150 ++GV) { 147 addVarToTlsTemplate(&State, &FieldBssTypes, NULL, &GV);
151 if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) {
152 addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV);
153 VarInfo Info; 148 VarInfo Info;
154 Info.TlsVar = GV; 149 Info.TlsVar = &GV;
155 Info.IsBss = true; 150 Info.IsBss = true;
156 Info.TemplateIndex = FieldBssTypes.size() - 1; 151 Info.TemplateIndex = FieldBssTypes.size() - 1;
157 TlsVars->push_back(Info); 152 TlsVars->push_back(Info);
158 } 153 }
159 } 154 }
160 // Add final alignment padding so that 155 // Add final alignment padding so that
161 // (struct tls_struct *) __nacl_read_tp() - 1 156 // (struct tls_struct *) __nacl_read_tp() - 1
162 // gives the correct, aligned start of the TLS variables given the 157 // gives the correct, aligned start of the TLS variables given the
163 // x86-style layout we are using. This requires some more bytes to 158 // x86-style layout we are using. This requires some more bytes to
164 // be memset() to zero at runtime. This wastage doesn't seem 159 // be memset() to zero at runtime. This wastage doesn't seem
(...skipping 59 matching lines...)
224 AlignmentVar->setName(AlignmentSymbol); 219 AlignmentVar->setName(AlignmentSymbol);
225 220
226 return TemplateType; 221 return TemplateType;
227 } 222 }
228 223
229 static void rewriteTlsVars(Module &M, std::vector<VarInfo> *TlsVars, 224 static void rewriteTlsVars(Module &M, std::vector<VarInfo> *TlsVars,
230 StructType *TemplateType) { 225 StructType *TemplateType) {
231 // Set up the intrinsic that reads the thread pointer. 226 // Set up the intrinsic that reads the thread pointer.
232 Function *ReadTpFunc = Intrinsic::getDeclaration(&M, Intrinsic::nacl_read_tp); 227 Function *ReadTpFunc = Intrinsic::getDeclaration(&M, Intrinsic::nacl_read_tp);
233 228
234 for (std::vector<VarInfo>::iterator VarInfo = TlsVars->begin(); 229 for (VarInfo &VarInfo : *TlsVars) {
235 VarInfo != TlsVars->end(); 230 GlobalVariable *Var = VarInfo.TlsVar;
236 ++VarInfo) { 231 while (!Var->use_empty()) {
237 GlobalVariable *Var = VarInfo->TlsVar;
238 while (Var->hasNUsesOrMore(1)) {
239 Use *U = &*Var->use_begin(); 232 Use *U = &*Var->use_begin();
240 Instruction *InsertPt = PhiSafeInsertPt(U); 233 Instruction *InsertPt = PhiSafeInsertPt(U);
241 Value *RawThreadPtr = CallInst::Create(ReadTpFunc, "tls_raw", InsertPt); 234 Value *RawThreadPtr = CallInst::Create(ReadTpFunc, "tls_raw", InsertPt);
242 Value *TypedThreadPtr = new BitCastInst( 235 Value *TypedThreadPtr = new BitCastInst(
243 RawThreadPtr, TemplateType->getPointerTo(), "tls_struct", InsertPt); 236 RawThreadPtr, TemplateType->getPointerTo(), "tls_struct", InsertPt);
244 SmallVector<Value*, 3> Indexes; 237 SmallVector<Value*, 3> Indexes;
245 // We use -1 because we use the x86-style TLS layout in which 238 // We use -1 because we use the x86-style TLS layout in which
246 // the TLS data is stored at addresses below the thread pointer. 239 // the TLS data is stored at addresses below the thread pointer.
247 // This is largely because a check in nacl_irt_thread_create() 240 // This is largely because a check in nacl_irt_thread_create()
248 // in irt/irt_thread.c requires the thread pointer to be a 241 // in irt/irt_thread.c requires the thread pointer to be a
249 // self-pointer on x86-32. 242 // self-pointer on x86-32.
250 // TODO(mseaborn): I intend to remove that check because it is 243 // TODO(mseaborn): I intend to remove that check because it is
251 // non-portable. In the mean time, we want PNaCl pexes to work 244 // non-portable. In the mean time, we want PNaCl pexes to work
252 // in older Chromium releases when translated to nexes. 245 // in older Chromium releases when translated to nexes.
253 Indexes.push_back(ConstantInt::get( 246 Indexes.push_back(ConstantInt::get(
254 M.getContext(), APInt(32, -1))); 247 M.getContext(), APInt(32, -1)));
255 Indexes.push_back(ConstantInt::get( 248 Indexes.push_back(ConstantInt::get(
256 M.getContext(), APInt(32, VarInfo->IsBss ? 1 : 0))); 249 M.getContext(), APInt(32, VarInfo.IsBss ? 1 : 0)));
257 Indexes.push_back(ConstantInt::get( 250 Indexes.push_back(ConstantInt::get(
258 M.getContext(), APInt(32, VarInfo->TemplateIndex))); 251 M.getContext(), APInt(32, VarInfo.TemplateIndex)));
259 Value *TlsField = GetElementPtrInst::Create( 252 Value *TlsField = GetElementPtrInst::Create(
260 TemplateType, TypedThreadPtr, Indexes, "field", InsertPt); 253 TemplateType, TypedThreadPtr, Indexes, "field", InsertPt);
261 PhiSafeReplaceUses(U, TlsField); 254 PhiSafeReplaceUses(U, TlsField);
262 } 255 }
263 VarInfo->TlsVar->eraseFromParent(); 256 Var->eraseFromParent();
264 } 257 }
265 } 258 }
266 259
267 static void replaceFunction(Module &M, const char *Name, Value *NewFunc) { 260 static void replaceFunction(Module &M, const char *Name, Value *NewFunc) {
268 if (Function *Func = M.getFunction(Name)) { 261 if (Function *Func = M.getFunction(Name)) {
269 if (Func->hasLocalLinkage()) 262 if (Func->hasLocalLinkage())
270 return; 263 return;
271 if (!Func->isDeclaration()) 264 if (!Func->isDeclaration())
272 report_fatal_error(std::string("Function already defined: ") + Name); 265 report_fatal_error(std::string("Function already defined: ") + Name);
273 Func->replaceAllUsesWith(NewFunc); 266 Func->replaceAllUsesWith(NewFunc);
(...skipping 53 matching lines...)
327 rewriteTlsVars(M, &TlsVars, TemplateType); 320 rewriteTlsVars(M, &TlsVars, TemplateType);
328 321
329 defineTlsLayoutFunctions(M); 322 defineTlsLayoutFunctions(M);
330 323
331 return true; 324 return true;
332 } 325 }
333 326
334 ModulePass *llvm::createExpandTlsPass() { 327 ModulePass *llvm::createExpandTlsPass() {
335 return new ExpandTls(); 328 return new ExpandTls();
336 } 329 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine