1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/* 2cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines * Copyright 2011-2012, The Android Open Source Project 3932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 4932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * you may not use this file except in compliance with the License. 6932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * You may obtain a copy of the License at 7932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 8932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 10932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Unless required by applicable law or agreed to in writing, software 11932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * See the License for the specific language governing permissions and 14932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * limitations under the License. 15932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */ 16932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 17932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <bcinfo/BitcodeTranslator.h> 1804261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines#include <bcinfo/BitcodeWrapper.h> 19932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <bcinfo/MetadataExtractor.h> 20932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 21e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/ADT/StringRef.h> 22e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Bitcode/ReaderWriter.h> 23c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include <llvm/IR/AssemblyAnnotationWriter.h> 24b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/LLVMContext.h> 25b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h> 26a630078b32eb37a8de91ae09e26babf235d4fc9fStephen Hines#include <llvm/Support/FileSystem.h> 27e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/ManagedStatic.h> 28e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/MemoryBuffer.h> 29e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/ToolOutputFile.h> 30e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 31932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <ctype.h> 32932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <dlfcn.h> 33932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdarg.h> 34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdint.h> 35932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdio.h> 36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdlib.h> 37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <string.h> 38932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <getopt.h> 39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 40932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <errno.h> 41932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <sys/stat.h> 42932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <sys/types.h> 43932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 44932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <unistd.h> 45932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 46e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <string> 47932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <vector> 48932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 49932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// This file corresponds to the standalone bcinfo tool. It prints a variety of 50932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// information about a supplied bitcode input file. 51932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 52e126b62760b4bf115cfed162f0234e4e722011dfStephen Hinesstd::string inFile; 53e126b62760b4bf115cfed162f0234e4e722011dfStephen Hinesstd::string outFile; 543ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesstd::string infoFile; 55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesextern int opterr; 57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesextern int optind; 58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 5904261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hinesbool translateFlag = false; 603ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesbool infoFlag = false; 613ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesbool verbose = true; 62932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 63932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic int parseOption(int argc, char** argv) { 64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines int c; 653ffc8330d765599e357197883f72c01bd43837c8Stephen Hines while ((c = getopt(argc, argv, "itv")) != -1) { 66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines opterr = 0; 67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines switch(c) { 69932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines case '?': 70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // ignore any error 71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines case 't': 7404261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines translateFlag = true; 75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 773ffc8330d765599e357197883f72c01bd43837c8Stephen Hines case 'i': 783ffc8330d765599e357197883f72c01bd43837c8Stephen Hines // Turn off verbose so that we only generate the .info file. 793ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFlag = true; 803ffc8330d765599e357197883f72c01bd43837c8Stephen Hines verbose = false; 813ffc8330d765599e357197883f72c01bd43837c8Stephen Hines break; 823ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 833ffc8330d765599e357197883f72c01bd43837c8Stephen Hines case 'v': 843ffc8330d765599e357197883f72c01bd43837c8Stephen Hines verbose = true; 853ffc8330d765599e357197883f72c01bd43837c8Stephen Hines break; 863ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines default: 88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // Critical error occurs 89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if(optind >= argc) { 95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "input file required\n"); 96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines inFile = argv[optind]; 100e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 101e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines int l = inFile.length(); 102e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (l > 3 && inFile[l-3] == '.' && inFile[l-2] == 'b' && inFile[l-1] == 'c') { 103e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines outFile = std::string(inFile.begin(), inFile.end() - 3) + ".ll"; 1043ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFile = std::string(inFile.begin(), inFile.end() - 3) + ".bcinfo"; 105e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } else { 106e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines outFile = inFile + ".ll"; 1073ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFile = inFile + ".bcinfo"; 108e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } 109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 1; 110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 113a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Grossstatic void dumpReduceInfo(FILE *info, const char *Kind, const char *Name) { 11479e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross if (Name) 11579e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross fprintf(info, " %s(%s)\n", Kind, Name); 11679e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross} 11779e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross 1183ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesstatic int dumpInfo(bcinfo::MetadataExtractor *ME) { 1193ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (!ME) { 1203ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 1; 1213ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1223ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1233ffc8330d765599e357197883f72c01bd43837c8Stephen Hines FILE *info = fopen(infoFile.c_str(), "w"); 1243ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (!info) { 1253ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "Could not open info file %s\n", infoFile.c_str()); 1263ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 2; 1273ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1283ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1294cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines fprintf(info, "exportVarCount: %zu\n", ME->getExportVarCount()); 1303ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **varNameList = ME->getExportVarNameList(); 1313ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportVarCount(); i++) { 1323ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%s\n", varNameList[i]); 1333ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1343ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1354cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines fprintf(info, "exportFuncCount: %zu\n", ME->getExportFuncCount()); 1363ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **funcNameList = ME->getExportFuncNameList(); 1373ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportFuncCount(); i++) { 1383ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%s\n", funcNameList[i]); 1393ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1403ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1414cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines fprintf(info, "exportForEachCount: %zu\n", 1423ffc8330d765599e357197883f72c01bd43837c8Stephen Hines ME->getExportForEachSignatureCount()); 1433ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **nameList = ME->getExportForEachNameList(); 1443ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const uint32_t *sigList = ME->getExportForEachSignatureList(); 145a668182c61d2f3079416317b6c2914428a6a4c7aChris Wailes const uint32_t *inputCountList = ME->getExportForEachInputCountList(); 1463ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) { 147a668182c61d2f3079416317b6c2914428a6a4c7aChris Wailes fprintf(info, "%u - %s - %u\n", sigList[i], nameList[i], 148a668182c61d2f3079416317b6c2914428a6a4c7aChris Wailes inputCountList[i]); 1493ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1503ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1511895ac12bda8ebb1097dd3336e0919e2f08cbc4aMatt Wala fprintf(info, "exportReduceCount: %zu\n", ME->getExportReduceCount()); 152a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce *reduceList = 153a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross ME->getExportReduceList(); 1541895ac12bda8ebb1097dd3336e0919e2f08cbc4aMatt Wala for (size_t i = 0; i < ME->getExportReduceCount(); i++) { 155a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce &reduce = reduceList[i]; 156a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross fprintf(info, "%u - %s - %u - %u\n", reduce.mSignature, reduce.mReduceName, 157a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross reduce.mInputCount, reduce.mAccumulatorDataSize); 158a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(info, "initializer", reduce.mInitializerName); 159a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(info, "accumulator", reduce.mAccumulatorName); 160a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(info, "combiner", reduce.mCombinerName); 161a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(info, "outconverter", reduce.mOutConverterName); 162a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(info, "halter", reduce.mHalterName); 16379e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross } 16479e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross 1654cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines fprintf(info, "objectSlotCount: %zu\n", ME->getObjectSlotCount()); 1663ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const uint32_t *slotList = ME->getObjectSlotList(); 1673ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getObjectSlotCount(); i++) { 1683ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%u\n", slotList[i]); 1693ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1703ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1713ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fclose(info); 1723ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 0; 1733ffc8330d765599e357197883f72c01bd43837c8Stephen Hines} 1743ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1753ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 176932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic void dumpMetadata(bcinfo::MetadataExtractor *ME) { 177932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!ME) { 178932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 179932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 180932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 181e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("RSFloatPrecision: "); 182e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines switch (ME->getRSFloatPrecision()) { 183e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines case bcinfo::RS_FP_Full: 184e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("Full\n\n"); 185e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 186e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines case bcinfo::RS_FP_Relaxed: 187e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("Relaxed\n\n"); 188e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 189e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines default: 190e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("UNKNOWN\n\n"); 191e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 192e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines } 193e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines 1944cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("exportVarCount: %zu\n", ME->getExportVarCount()); 195569986da116ed602c752395f9563260db38f6945Stephen Hines const char **varNameList = ME->getExportVarNameList(); 196569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportVarCount(); i++) { 1974cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("var[%zu]: %s\n", i, varNameList[i]); 198569986da116ed602c752395f9563260db38f6945Stephen Hines } 199569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 200569986da116ed602c752395f9563260db38f6945Stephen Hines 2014cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("exportFuncCount: %zu\n", ME->getExportFuncCount()); 202569986da116ed602c752395f9563260db38f6945Stephen Hines const char **funcNameList = ME->getExportFuncNameList(); 203569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportFuncCount(); i++) { 2044cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("func[%zu]: %s\n", i, funcNameList[i]); 205569986da116ed602c752395f9563260db38f6945Stephen Hines } 206569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 20733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 2084cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("exportForEachSignatureCount: %zu\n", 20933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines ME->getExportForEachSignatureCount()); 210cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines const char **nameList = ME->getExportForEachNameList(); 21133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines const uint32_t *sigList = ME->getExportForEachSignatureList(); 212a668182c61d2f3079416317b6c2914428a6a4c7aChris Wailes const uint32_t *inputCountList = ME->getExportForEachInputCountList(); 21333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) { 21433cda5cf335afc6aa2dbe02062bc9e6649e1f87cDavid Gross printf("exportForEachSignatureList[%zu]: %s - 0x%08x - %u\n", i, nameList[i], 215a668182c61d2f3079416317b6c2914428a6a4c7aChris Wailes sigList[i], inputCountList[i]); 21633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines } 217569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 21833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 2191895ac12bda8ebb1097dd3336e0919e2f08cbc4aMatt Wala printf("exportReduceCount: %zu\n", ME->getExportReduceCount()); 220a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce *reduceList = ME->getExportReduceList(); 2211895ac12bda8ebb1097dd3336e0919e2f08cbc4aMatt Wala for (size_t i = 0; i < ME->getExportReduceCount(); i++) { 222a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce &reduce = reduceList[i]; 223a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross printf("exportReduceList[%zu]: %s - 0x%08x - %u - %u\n", i, reduce.mReduceName, 224a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross reduce.mSignature, reduce.mInputCount, reduce.mAccumulatorDataSize); 225a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(stdout, "initializer", reduce.mInitializerName); 226a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(stdout, "accumulator", reduce.mAccumulatorName); 227a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(stdout, "combiner", reduce.mCombinerName); 228a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(stdout, "outconverter", reduce.mOutConverterName); 229a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross dumpReduceInfo(stdout, "halter", reduce.mHalterName); 23079e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross } 23179e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross printf("\n"); 23279e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross 2334cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("pragmaCount: %zu\n", ME->getPragmaCount()); 234932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **keyList = ME->getPragmaKeyList(); 235932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **valueList = ME->getPragmaValueList(); 236932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getPragmaCount(); i++) { 2374cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("pragma[%zu]: %s - %s\n", i, keyList[i], valueList[i]); 238932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 239569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 240932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 2414cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("objectSlotCount: %zu\n", ME->getObjectSlotCount()); 242932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const uint32_t *slotList = ME->getObjectSlotList(); 243932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getObjectSlotCount(); i++) { 2444cb4c555b4d339644fe9d13cdc45093721d0896eStephen Hines printf("objectSlotList[%zu]: %u\n", i, slotList[i]); 245932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 246569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 247932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 248932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 249932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 250932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 251932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 252932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic size_t readBitcode(const char **bitcode) { 253e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (!inFile.length()) { 254932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "input file required\n"); 255e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 256932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 257932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 258932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines struct stat statInFile; 259e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (stat(inFile.c_str(), &statInFile) < 0) { 260932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno)); 261e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 262932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 263932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 264932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!S_ISREG(statInFile.st_mode)) { 265932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Input file should be a regular file.\n"); 266e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 267932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 268932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 269e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines FILE *in = fopen(inFile.c_str(), "r"); 270932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!in) { 271e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not open input file %s\n", inFile.c_str()); 272e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 273932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 274932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 275932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = statInFile.st_size; 276932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 277932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *bitcode = (const char*) calloc(1, bitcodeSize + 1); 278932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t nread = fread((void*) *bitcode, 1, bitcodeSize, in); 279932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 280932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (nread != bitcodeSize) 281e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not read all of file %s\n", inFile.c_str()); 282932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 283932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fclose(in); 284932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return nread; 285932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 286932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 287932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 288932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic void releaseBitcode(const char **bitcode) { 289932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (bitcode && *bitcode) { 290932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines free((void*) *bitcode); 291900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes *bitcode = nullptr; 292932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 293932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 294932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 295932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 296932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 297932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesint main(int argc, char** argv) { 298932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if(!parseOption(argc, argv)) { 299932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to parse option\n"); 300932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 1; 301932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 302932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 303900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes const char *bitcode = nullptr; 304932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = readBitcode(&bitcode); 305932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 30604261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines unsigned int version = 0; 307932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 30804261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize); 30904261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) { 31004261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines version = bcWrapper.getTargetAPI(); 3113ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 3123ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("Found bitcodeWrapper\n"); 3133ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 31404261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines } else if (translateFlag) { 315932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines version = 12; 316932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 317932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3183ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 3193ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("targetAPI: %u\n", version); 3203ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion()); 3213ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel()); 3223ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 32304261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines 324d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<bcinfo::BitcodeTranslator> BT; 325e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT.reset(new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version)); 326932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!BT->translate()) { 327932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to translate bitcode\n"); 32804261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 3; 329932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 330932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 331d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<bcinfo::MetadataExtractor> ME; 332e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines ME.reset(new bcinfo::MetadataExtractor(BT->getTranslatedBitcode(), 333e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT->getTranslatedBitcodeSize())); 334932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!ME->extract()) { 335932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to get metadata\n"); 33604261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 4; 337932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 338932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3393ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 3403ffc8330d765599e357197883f72c01bd43837c8Stephen Hines dumpMetadata(ME.get()); 341e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3423ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char *translatedBitcode = BT->getTranslatedBitcode(); 3433ffc8330d765599e357197883f72c01bd43837c8Stephen Hines size_t translatedBitcodeSize = BT->getTranslatedBitcodeSize(); 344e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 345f5b49a0ca149b09c8306b86db9f3aca703c4acd5Pirama Arumuga Nainar llvm::LLVMContext ctx; 3463ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::llvm_shutdown_obj called_on_exit; 347e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 348d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<llvm::MemoryBuffer> mem; 349e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 350579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines mem = llvm::MemoryBuffer::getMemBuffer( 3513ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::StringRef(translatedBitcode, translatedBitcodeSize), 352579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines inFile.c_str(), false); 353e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 354d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<llvm::Module> module; 3558e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar llvm::ErrorOr<std::unique_ptr<llvm::Module> > moduleOrError = 3568e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar llvm::parseBitcodeFile(mem.get()->getMemBufferRef(), ctx); 357d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::error_code ec = moduleOrError.getError(); 358c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray if (!ec) { 3598e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar module = std::move(moduleOrError.get()); 3608e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar ec = module->materializeAll(); 361c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray } 3623ffc8330d765599e357197883f72c01bd43837c8Stephen Hines std::string errmsg; 363c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray if (ec) { 364c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray errmsg = ec.message(); 3653ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module.reset(); 3663ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (errmsg.size()) { 3673ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "error: %s\n", errmsg.c_str()); 3683ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } else { 3693ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "error: failed to parse bitcode file\n"); 3703ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 3713ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 5; 372e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } 373e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 374d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<llvm::tool_output_file> tof( 375579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines new llvm::tool_output_file(outFile.c_str(), ec, 376c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray llvm::sys::fs::F_None)); 377d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::unique_ptr<llvm::AssemblyAnnotationWriter> ann; 3783ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module->print(tof->os(), ann.get()); 3793ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 3803ffc8330d765599e357197883f72c01bd43837c8Stephen Hines tof->keep(); 3813ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 382932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3833ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (infoFlag) { 3843ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (dumpInfo(ME.get()) != 0) { 3853ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "Error dumping info file\n"); 3863ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 6; 3873ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 3883ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 389932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 390932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines releaseBitcode(&bitcode); 391932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 392932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 393932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 394