Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceGlobalInits.h - Global declarations -------*- C++ -*-===// | 1 //===- subzero/src/IceGlobalInits.h - Global declarations -------*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 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 /// \file | 10 /// \file |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 GlobalDeclarationKind getKind() const { return Kind; } | 64 GlobalDeclarationKind getKind() const { return Kind; } |
| 65 const IceString &getName() const { return Name; } | 65 const IceString &getName() const { return Name; } |
| 66 void setName(const IceString &NewName) { | 66 void setName(const IceString &NewName) { |
| 67 Name = getSuppressMangling() ? NewName : mangleName(NewName); | 67 Name = getSuppressMangling() ? NewName : mangleName(NewName); |
| 68 } | 68 } |
| 69 bool hasName() const { return !Name.empty(); } | 69 bool hasName() const { return !Name.empty(); } |
| 70 bool isInternal() const { | 70 bool isInternal() const { |
| 71 return Linkage == llvm::GlobalValue::InternalLinkage; | 71 return Linkage == llvm::GlobalValue::InternalLinkage; |
| 72 } | 72 } |
| 73 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; } | 73 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; } |
| 74 void setLinkage(llvm::GlobalValue::LinkageTypes l) { Linkage = l; } | |
|
Mark Seaborn
2016/03/09 03:37:15
Style nit: should be "L"
Sean Klein
2016/03/10 23:45:22
Done.
| |
| 74 bool isExternal() const { | 75 bool isExternal() const { |
| 75 return Linkage == llvm::GlobalValue::ExternalLinkage; | 76 return Linkage == llvm::GlobalValue::ExternalLinkage; |
| 76 } | 77 } |
| 77 virtual ~GlobalDeclaration() = default; | 78 virtual ~GlobalDeclaration() = default; |
| 78 | 79 |
| 79 /// Prints out type of the global declaration. | 80 /// Prints out type of the global declaration. |
| 80 virtual void dumpType(Ostream &Stream) const = 0; | 81 virtual void dumpType(Ostream &Stream) const = 0; |
| 81 | 82 |
| 82 /// Prints out the global declaration. | 83 /// Prints out the global declaration. |
| 83 virtual void dump(Ostream &Stream) const = 0; | 84 virtual void dump(Ostream &Stream) const = 0; |
| 84 | 85 |
| 85 /// Returns true if when emitting names, we should suppress mangling. | 86 /// Returns true if when emitting names, we should suppress mangling. |
| 86 virtual bool getSuppressMangling() const = 0; | 87 virtual bool getSuppressMangling() const = 0; |
| 87 | 88 |
| 88 /// Returns textual name of linkage. | 89 /// Returns textual name of linkage. |
| 89 const char *getLinkageName() const { | 90 const char *getLinkageName() const { |
| 90 return isInternal() ? "internal" : "external"; | 91 return isInternal() ? "internal" : "external"; |
| 91 } | 92 } |
| 92 | 93 |
| 94 /// Returns true if the name of this GlobalDeclaration indicates that it | |
| 95 /// should have ExternalLinkage (as a special case). | |
| 96 virtual bool isPNaClABIExternalName() const = 0; | |
| 97 | |
| 93 protected: | 98 protected: |
| 94 GlobalDeclaration(GlobalDeclarationKind Kind, | 99 GlobalDeclaration(GlobalDeclarationKind Kind, |
| 95 llvm::GlobalValue::LinkageTypes Linkage) | 100 llvm::GlobalValue::LinkageTypes Linkage) |
| 96 : Kind(Kind), Linkage(Linkage) {} | 101 : Kind(Kind), Linkage(Linkage) {} |
| 97 | 102 |
| 98 /// Returns true if linkage is defined correctly for the global declaration, | 103 /// Returns true if linkage is defined correctly for the global declaration, |
| 99 /// based on default rules. | 104 /// based on default rules. |
| 100 bool verifyLinkageDefault(const GlobalContext *Ctx) const { | 105 bool verifyLinkageDefault(const GlobalContext *Ctx) const { |
| 101 switch (Linkage) { | 106 switch (Linkage) { |
| 102 default: | 107 default: |
| 103 return false; | 108 return false; |
| 104 case llvm::GlobalValue::InternalLinkage: | 109 case llvm::GlobalValue::InternalLinkage: |
| 105 return true; | 110 return true; |
| 106 case llvm::GlobalValue::ExternalLinkage: | 111 case llvm::GlobalValue::ExternalLinkage: |
| 107 return Ctx->getFlags().getAllowExternDefinedSymbols(); | 112 return Ctx->getFlags().getAllowExternDefinedSymbols(); |
| 108 } | 113 } |
| 109 } | 114 } |
| 110 | 115 |
| 111 const GlobalDeclarationKind Kind; | 116 const GlobalDeclarationKind Kind; |
| 112 const llvm::GlobalValue::LinkageTypes Linkage; | 117 llvm::GlobalValue::LinkageTypes Linkage; |
| 113 IceString Name; | 118 IceString Name; |
| 114 }; | 119 }; |
| 115 | 120 |
| 116 /// Models a function declaration. This includes the type signature of the | 121 /// Models a function declaration. This includes the type signature of the |
| 117 /// function, its calling conventions, and its linkage. | 122 /// function, its calling conventions, and its linkage. |
| 118 class FunctionDeclaration : public GlobalDeclaration { | 123 class FunctionDeclaration : public GlobalDeclaration { |
| 119 FunctionDeclaration() = delete; | 124 FunctionDeclaration() = delete; |
| 120 FunctionDeclaration(const FunctionDeclaration &) = delete; | 125 FunctionDeclaration(const FunctionDeclaration &) = delete; |
| 121 FunctionDeclaration &operator=(const FunctionDeclaration &) = delete; | 126 FunctionDeclaration &operator=(const FunctionDeclaration &) = delete; |
| 122 | 127 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 135 bool isProto() const { return IsProto; } | 140 bool isProto() const { return IsProto; } |
| 136 static bool classof(const GlobalDeclaration *Addr) { | 141 static bool classof(const GlobalDeclaration *Addr) { |
| 137 return Addr->getKind() == FunctionDeclarationKind; | 142 return Addr->getKind() == FunctionDeclarationKind; |
| 138 } | 143 } |
| 139 void dumpType(Ostream &Stream) const final; | 144 void dumpType(Ostream &Stream) const final; |
| 140 void dump(Ostream &Stream) const final; | 145 void dump(Ostream &Stream) const final; |
| 141 bool getSuppressMangling() const final { return isExternal() && IsProto; } | 146 bool getSuppressMangling() const final { return isExternal() && IsProto; } |
| 142 | 147 |
| 143 /// Returns true if linkage is correct for the function declaration. | 148 /// Returns true if linkage is correct for the function declaration. |
| 144 bool verifyLinkageCorrect(const GlobalContext *Ctx) const { | 149 bool verifyLinkageCorrect(const GlobalContext *Ctx) const { |
| 145 if (isPNaClABIExternalName() || isIntrinsicName(Ctx)) | 150 if (isIntrinsicName(Ctx)) { |
| 146 return Linkage == llvm::GlobalValue::ExternalLinkage; | 151 return Linkage == llvm::GlobalValue::ExternalLinkage; |
| 147 return verifyLinkageDefault(Ctx); | 152 } else if (isPNaClABIExternalName()) { |
|
Mark Seaborn
2016/03/09 03:37:15
Isn't this equivalent to what this function was do
Sean Klein
2016/03/10 23:45:22
Agreed -- sorry, changed back.
| |
| 153 return Linkage == llvm::GlobalValue::ExternalLinkage; | |
| 154 } else { | |
| 155 return verifyLinkageDefault(Ctx); | |
| 156 } | |
| 148 } | 157 } |
| 149 | 158 |
| 150 /// Validates that the type signature of the function is correct. Returns true | 159 /// Validates that the type signature of the function is correct. Returns true |
| 151 /// if valid. | 160 /// if valid. |
| 152 bool validateTypeSignature(const GlobalContext *Ctx) const { | 161 bool validateTypeSignature(const GlobalContext *Ctx) const { |
| 153 bool IsIntrinsic; | 162 bool IsIntrinsic; |
| 154 if (const Intrinsics::FullIntrinsicInfo *Info = | 163 if (const Intrinsics::FullIntrinsicInfo *Info = |
| 155 getIntrinsicInfo(Ctx, &IsIntrinsic)) | 164 getIntrinsicInfo(Ctx, &IsIntrinsic)) |
| 156 return validateIntrinsicTypeSignature(Info); | 165 return validateIntrinsicTypeSignature(Info); |
| 157 return !IsIntrinsic && validateRegularTypeSignature(); | 166 return !IsIntrinsic && validateRegularTypeSignature(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 177 const Ice::FuncSigType Signature; | 186 const Ice::FuncSigType Signature; |
| 178 llvm::CallingConv::ID CallingConv; | 187 llvm::CallingConv::ID CallingConv; |
| 179 const bool IsProto; | 188 const bool IsProto; |
| 180 | 189 |
| 181 FunctionDeclaration(const FuncSigType &Signature, | 190 FunctionDeclaration(const FuncSigType &Signature, |
| 182 llvm::CallingConv::ID CallingConv, | 191 llvm::CallingConv::ID CallingConv, |
| 183 llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) | 192 llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) |
| 184 : GlobalDeclaration(FunctionDeclarationKind, Linkage), | 193 : GlobalDeclaration(FunctionDeclarationKind, Linkage), |
| 185 Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {} | 194 Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {} |
| 186 | 195 |
| 187 bool isPNaClABIExternalName() const { | 196 bool isPNaClABIExternalName() const override { |
| 188 const char *Name = getName().c_str(); | 197 static constexpr char Start[] = "_start"; |
|
Mark Seaborn
2016/03/09 03:37:15
Why not just write "_start" on the following line?
Sean Klein
2016/03/10 23:45:22
Done, and also with "__pnacl_pso_root".
| |
| 189 return strcmp(Name, "_start") == 0 || strcmp(Name, "__pnacl_pso_root") == 0; | 198 return getName() == Start; |
| 190 } | 199 } |
| 191 | 200 |
| 192 bool isIntrinsicName(const GlobalContext *Ctx) const { | 201 bool isIntrinsicName(const GlobalContext *Ctx) const { |
| 193 bool IsIntrinsic; | 202 bool IsIntrinsic; |
| 194 getIntrinsicInfo(Ctx, &IsIntrinsic); | 203 getIntrinsicInfo(Ctx, &IsIntrinsic); |
| 195 return IsIntrinsic; | 204 return IsIntrinsic; |
| 196 } | 205 } |
| 197 | 206 |
| 198 bool validateRegularTypeSignature() const; | 207 bool validateRegularTypeSignature() const; |
| 199 | 208 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 DataInitializer &operator=(const DataInitializer &) = delete; | 250 DataInitializer &operator=(const DataInitializer &) = delete; |
| 242 | 251 |
| 243 public: | 252 public: |
| 244 template <class... Args> | 253 template <class... Args> |
| 245 static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) { | 254 static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) { |
| 246 return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...); | 255 return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...); |
| 247 } | 256 } |
| 248 | 257 |
| 249 const DataVecType &getContents() const { return Contents; } | 258 const DataVecType &getContents() const { return Contents; } |
| 250 SizeT getNumBytes() const final { return Contents.size(); } | 259 SizeT getNumBytes() const final { return Contents.size(); } |
| 251 void dump(Ostream &Stream) const final; | 260 void dump(Ostream &Stream) const override final; |
|
Karl
2016/03/09 17:06:50
Doesn't final imply override? Why are both necessa
Sean Klein
2016/03/10 23:45:22
This was causing the following clang error (hence
| |
| 252 static bool classof(const Initializer *D) { | 261 static bool classof(const Initializer *D) { |
| 253 return D->getKind() == DataInitializerKind; | 262 return D->getKind() == DataInitializerKind; |
| 254 } | 263 } |
| 255 | 264 |
| 256 private: | 265 private: |
| 257 ENABLE_MAKE_UNIQUE; | 266 ENABLE_MAKE_UNIQUE; |
| 258 | 267 |
| 259 DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values) | 268 DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values) |
| 260 : Initializer(DataInitializerKind), Contents(Values.size()) { | 269 : Initializer(DataInitializerKind), Contents(Values.size()) { |
| 261 for (SizeT I = 0; I < Values.size(); ++I) | 270 for (SizeT I = 0; I < Values.size(); ++I) |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 /// Adds Initializer to the list of initializers. Takes ownership of the | 406 /// Adds Initializer to the list of initializers. Takes ownership of the |
| 398 /// initializer. | 407 /// initializer. |
| 399 void addInitializer(std::unique_ptr<Initializer> Initializer) { | 408 void addInitializer(std::unique_ptr<Initializer> Initializer) { |
| 400 const bool OldSuppressMangling = getSuppressMangling(); | 409 const bool OldSuppressMangling = getSuppressMangling(); |
| 401 Initializers->emplace_back(std::move(Initializer)); | 410 Initializers->emplace_back(std::move(Initializer)); |
| 402 HasInitializer = true; | 411 HasInitializer = true; |
| 403 // The getSuppressMangling() logic depends on whether the global variable | 412 // The getSuppressMangling() logic depends on whether the global variable |
| 404 // has initializers. If its value changed as a result of adding an | 413 // has initializers. If its value changed as a result of adding an |
| 405 // initializer, then make sure we haven't previously set the name based on | 414 // initializer, then make sure we haven't previously set the name based on |
| 406 // faulty SuppressMangling logic. | 415 // faulty SuppressMangling logic. |
| 407 const bool SameMangling = (OldSuppressMangling == getSuppressMangling()); | 416 const bool SameMangling = (OldSuppressMangling == getSuppressMangling()); |
|
Jim Stichnoth
2016/03/09 16:29:35
Just FYI.
The cross test framework involves mangl
Sean Klein
2016/03/10 23:45:22
I'll add an assert to "setLinkage" that the name i
| |
| 408 (void)SameMangling; | 417 (void)SameMangling; |
| 409 assert(!Name.empty() || SameMangling); | 418 assert(!Name.empty() || SameMangling); |
| 410 } | 419 } |
| 411 | 420 |
| 412 /// Prints out type for initializer associated with the declaration to Stream. | 421 /// Prints out type for initializer associated with the declaration to Stream. |
| 413 void dumpType(Ostream &Stream) const final; | 422 void dumpType(Ostream &Stream) const final; |
| 414 | 423 |
| 415 /// Prints out the definition of the global variable declaration (including | 424 /// Prints out the definition of the global variable declaration (including |
| 416 /// initialization). | 425 /// initialization). |
| 417 virtual void dump(Ostream &Stream) const; | 426 virtual void dump(Ostream &Stream) const override; |
| 418 | 427 |
| 419 /// Returns true if linkage is correct for the variable declaration. | 428 /// Returns true if linkage is correct for the variable declaration. |
| 420 bool verifyLinkageCorrect(const GlobalContext *Ctx) const { | 429 bool verifyLinkageCorrect(const GlobalContext *Ctx) const { |
| 430 if (isPNaClABIExternalName()) { | |
| 431 return Linkage == llvm::GlobalValue::ExternalLinkage; | |
| 432 } | |
| 421 return verifyLinkageDefault(Ctx); | 433 return verifyLinkageDefault(Ctx); |
| 422 } | 434 } |
| 423 | 435 |
| 424 static bool classof(const GlobalDeclaration *Addr) { | 436 static bool classof(const GlobalDeclaration *Addr) { |
| 425 return Addr->getKind() == VariableDeclarationKind; | 437 return Addr->getKind() == VariableDeclarationKind; |
| 426 } | 438 } |
| 427 | 439 |
| 428 bool getSuppressMangling() const final { | 440 bool getSuppressMangling() const final { |
| 429 if (ForceSuppressMangling) | 441 if (ForceSuppressMangling) |
| 430 return true; | 442 return true; |
| 431 return isExternal() && !hasInitializer(); | 443 return isExternal() && !hasInitializer(); |
| 432 } | 444 } |
| 433 | 445 |
| 434 void discardInitializers() { Initializers = nullptr; } | 446 void discardInitializers() { Initializers = nullptr; } |
| 435 | 447 |
| 448 bool isPNaClABIExternalName() const override { | |
| 449 static constexpr char PnaclPsoRoot[] = "__pnacl_pso_root"; | |
| 450 return getName() == PnaclPsoRoot; | |
|
Jim Stichnoth
2016/03/09 16:29:35
Should this be conditional on GlobalContext::getFl
Sean Klein
2016/03/10 23:45:22
Is there a reason dynamic linking couldn't be supp
Jim Stichnoth
2016/03/11 01:20:29
Sorry, I got confused about the scope of this chan
| |
| 451 } | |
| 452 | |
| 436 private: | 453 private: |
| 437 /// List of initializers for the declared variable. | 454 /// List of initializers for the declared variable. |
| 438 std::unique_ptr<InitializerListType> Initializers; | 455 std::unique_ptr<InitializerListType> Initializers; |
| 439 bool HasInitializer = false; | 456 bool HasInitializer = false; |
| 440 /// The alignment of the declared variable. | 457 /// The alignment of the declared variable. |
| 441 uint32_t Alignment = 0; | 458 uint32_t Alignment = 0; |
| 442 /// True if a declared (global) constant. | 459 /// True if a declared (global) constant. |
| 443 bool IsConstant = false; | 460 bool IsConstant = false; |
| 444 /// If set to true, force getSuppressMangling() to return true. | 461 /// If set to true, force getSuppressMangling() to return true. |
| 445 const bool ForceSuppressMangling; | 462 const bool ForceSuppressMangling; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 461 template <class StreamType> | 478 template <class StreamType> |
| 462 inline StreamType &operator<<(StreamType &Stream, | 479 inline StreamType &operator<<(StreamType &Stream, |
| 463 const GlobalDeclaration &Addr) { | 480 const GlobalDeclaration &Addr) { |
| 464 Addr.dump(Stream); | 481 Addr.dump(Stream); |
| 465 return Stream; | 482 return Stream; |
| 466 } | 483 } |
| 467 | 484 |
| 468 } // end of namespace Ice | 485 } // end of namespace Ice |
| 469 | 486 |
| 470 #endif // SUBZERO_SRC_ICEGLOBALINITS_H | 487 #endif // SUBZERO_SRC_ICEGLOBALINITS_H |
| OLD | NEW |