NVPTXAssignValidGlobalNames.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //===-- NVPTXAssignValidGlobalNames.cpp - Assign valid names to globals ---===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Clean up the names of global variables in the module to not contain symbols
  10. // that are invalid in PTX.
  11. //
  12. // Currently NVPTX, like other backends, relies on generic symbol name
  13. // sanitizing done by MC. However, the ptxas assembler is more stringent and
  14. // disallows some additional characters in symbol names. This pass makes sure
  15. // such names do not reach MC at all.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #include "NVPTX.h"
  19. #include "llvm/IR/Function.h"
  20. #include "llvm/IR/GlobalVariable.h"
  21. #include "llvm/IR/LegacyPassManager.h"
  22. #include "llvm/IR/Module.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. #include <string>
  25. using namespace llvm;
  26. namespace {
  27. /// NVPTXAssignValidGlobalNames
  28. class NVPTXAssignValidGlobalNames : public ModulePass {
  29. public:
  30. static char ID;
  31. NVPTXAssignValidGlobalNames() : ModulePass(ID) {}
  32. bool runOnModule(Module &M) override;
  33. /// Clean up the name to remove symbols invalid in PTX.
  34. std::string cleanUpName(StringRef Name);
  35. };
  36. }
  37. char NVPTXAssignValidGlobalNames::ID = 0;
  38. namespace llvm {
  39. void initializeNVPTXAssignValidGlobalNamesPass(PassRegistry &);
  40. }
  41. INITIALIZE_PASS(NVPTXAssignValidGlobalNames, "nvptx-assign-valid-global-names",
  42. "Assign valid PTX names to globals", false, false)
  43. bool NVPTXAssignValidGlobalNames::runOnModule(Module &M) {
  44. for (GlobalVariable &GV : M.globals()) {
  45. // We are only allowed to rename local symbols.
  46. if (GV.hasLocalLinkage()) {
  47. // setName doesn't do extra work if the name does not change.
  48. // Note: this does not create collisions - if setName is asked to set the
  49. // name to something that already exists, it adds a proper postfix to
  50. // avoid collisions.
  51. GV.setName(cleanUpName(GV.getName()));
  52. }
  53. }
  54. // Do the same for local functions.
  55. for (Function &F : M.functions())
  56. if (F.hasLocalLinkage())
  57. F.setName(cleanUpName(F.getName()));
  58. return true;
  59. }
  60. std::string NVPTXAssignValidGlobalNames::cleanUpName(StringRef Name) {
  61. std::string ValidName;
  62. raw_string_ostream ValidNameStream(ValidName);
  63. for (char C : Name) {
  64. if (C == '.' || C == '@') {
  65. ValidNameStream << "_$_";
  66. } else {
  67. ValidNameStream << C;
  68. }
  69. }
  70. return ValidNameStream.str();
  71. }
  72. ModulePass *llvm::createNVPTXAssignValidGlobalNamesPass() {
  73. return new NVPTXAssignValidGlobalNames();
  74. }