slang_bitcode_gen.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright 2015, The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "bcinfo/BitcodeWrapper.h"
  17. #include "llvm/Support/raw_ostream.h"
  18. #include "BitWriter_2_9/ReaderWriter_2_9.h"
  19. #include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
  20. #include "BitWriter_3_2/ReaderWriter_3_2.h"
  21. #include "slang_assert.h"
  22. #include "slang_bitcode_gen.h"
  23. #include "slang_version.h"
  24. #include "llvm/Bitcode/ReaderWriter.h"
  25. namespace slang {
  26. void writeBitcode(llvm::raw_ostream &Out,
  27. const llvm::Module &M,
  28. uint32_t TargetAPI,
  29. uint32_t OptimizationLevel,
  30. bool GenerateDebugInfo) {
  31. std::string BitcodeStr;
  32. llvm::raw_string_ostream Bitcode(BitcodeStr);
  33. // The older bitcode writers will produce invalid bitcode if the -g
  34. // flag is set using WriteBitcodeToFile. As such we use the ToT writer
  35. // when -g is set. However, this will produce a bitcode file linked to
  36. // this version of LLVM as the debug info format can change between
  37. // versions.
  38. // If bcc receives a bitcode file with a format of debug info
  39. // which is either ahead or behind the version it is expecting it will
  40. // fail the verification stage. Failing this stage results in the bitcode
  41. // loader returning null and the compiler will terminate abruptly. Bitcode
  42. // files with debug info are as such only capable of targeting devices with
  43. // LLVM libraries with the same debug info version as the version of slang
  44. // which was used to compile the file. This is due to the fact that LLVM
  45. // offers no backwards or forwards compatibility guarantee for its debug
  46. // bitcode. At the moment the only practical guarantee which can be made
  47. // is that the debug bitcode emitted by any slang will work with the bcc
  48. // version which was newest at the time when llvm-rs-cc was built.
  49. if (GenerateDebugInfo) {
  50. llvm::WriteBitcodeToFile(&M, Bitcode);
  51. } else {
  52. // Create the bitcode.
  53. switch (TargetAPI) {
  54. case SLANG_HC_TARGET_API:
  55. case SLANG_HC_MR1_TARGET_API:
  56. case SLANG_HC_MR2_TARGET_API: {
  57. // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
  58. llvm_2_9::WriteBitcodeToFile(&M, Bitcode);
  59. break;
  60. }
  61. case SLANG_ICS_TARGET_API:
  62. case SLANG_ICS_MR1_TARGET_API: {
  63. // ICS targets must use the LLVM 2.9_func BitcodeWriter
  64. llvm_2_9_func::WriteBitcodeToFile(&M, Bitcode);
  65. break;
  66. }
  67. default: {
  68. if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
  69. (TargetAPI < SLANG_MINIMUM_TARGET_API ||
  70. TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
  71. slangAssert(false && "Invalid target API value");
  72. }
  73. // Switch to the 3.2 BitcodeWriter by default, and don't use
  74. // LLVM's included BitcodeWriter at all (for now).
  75. llvm_3_2::WriteBitcodeToFile(&M, Bitcode);
  76. break;
  77. }
  78. }
  79. }
  80. const uint32_t CompilerVersion = SlangVersion::CURRENT;
  81. // Create the bitcode wrapper.
  82. bcinfo::AndroidBitcodeWrapper Wrapper;
  83. size_t ActualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
  84. &Wrapper, Bitcode.str().length(), TargetAPI,
  85. CompilerVersion, OptimizationLevel);
  86. slangAssert(ActualWrapperLen > 0);
  87. // Write out the file.
  88. Out.write(reinterpret_cast<char*>(&Wrapper), ActualWrapperLen);
  89. Out << Bitcode.str();
  90. }
  91. } // namespace slang