2394de9b37
SWDEV-198885 - [CQE][OCL][NAVI10][NAVI14 ] compiler temps not generated
Blender 2.8 spawns a new process for each kernel to be compiled. This makes saving temporaries impossible, since all of the kernels will have the same file names.
1. Add a formatting field %pid% to the dump prefix of -save-temps/-save-temps-all. The runtime will replace this field with the PID of the current process.
ReviewBoardURL = http://ocltc.amd.com/reviews/r/17832/diff/
Affected files ...
... //depot/stg/opencl/drivers/opencl/compiler/lib/utils/options.cpp#45 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/utils/options.hpp#21 edit
[ROCm/clr commit: 133a9ef59b]
344 строки
11 KiB
C++
344 строки
11 KiB
C++
//
|
|
// Copyright (c) 2009 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
|
|
#ifndef _UTILS_OPTIONS_HPP_
|
|
#define _UTILS_OPTIONS_HPP_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <cstdio>
|
|
#include "top.hpp"
|
|
#include "library.hpp"
|
|
#include <cassert>
|
|
#include <sstream>
|
|
#ifdef __linux__
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef _WIN32
|
|
#include <process.h>
|
|
#include <cstdio>
|
|
#endif
|
|
|
|
namespace amd {
|
|
|
|
class Device;
|
|
|
|
namespace option {
|
|
|
|
// Option Type : Info[0:5]
|
|
enum OptionType {
|
|
OT_BOOL,
|
|
OT_INT32,
|
|
OT_UINT32,
|
|
OT_CSTRING,
|
|
OT_UCHAR,
|
|
OT_MASK = 0x3f
|
|
};
|
|
|
|
/*
|
|
Option's Attributes : Info[6:31]
|
|
|
|
OxA_<sth> : Only one in each group is required.
|
|
OA_<sth> : Each one is independent, all OA_<sth> can be OR'ed together.
|
|
*/
|
|
|
|
// Option Value Attributes
|
|
enum OptionValue {
|
|
OVA_OPTIONAL = 0x00, // value is optional
|
|
OVA_REQUIRED = 0x40, // value is required to appear;
|
|
OVA_DISALLOWED = 0x80, // value may not be specified.
|
|
OVA_MASK = 0xC0
|
|
};
|
|
|
|
// Option Form Attributes
|
|
enum OptionForm {
|
|
OFA_NORMAL = 0x000, // normal form, no prefix
|
|
OFA_PREFIX_F = 0x100, // -f<flag>, machine-independent
|
|
OFA_PREFIX_M = 0x200, // -m<flag>, machine-dependent
|
|
OFA_PREFIX_W = 0x300, // -W<flag>, warning (TODO)
|
|
OFA_MASK = 0x300
|
|
};
|
|
|
|
// Option Group, at least one must be used.
|
|
enum OptionGroup {
|
|
OA_RUNTIME = 0x400,
|
|
OA_CLC = 0x800,
|
|
OA_LINK_EXE = 0x1000,
|
|
OA_LINK_LIB = 0x2000
|
|
};
|
|
|
|
// Option Value Separator, at least one must be used.
|
|
enum OptionValueSeparator {
|
|
OA_SEPARATOR_NONE = 0x4000,
|
|
OA_SEPARATOR_EQUAL = 0x8000,
|
|
OA_SEPARATOR_SPACE = 0x10000
|
|
};
|
|
|
|
// Option visibility : at least one must be used.
|
|
enum OptionVisibility {
|
|
OVIS_PUBLIC = 0x00000, // ducumented
|
|
OVIS_SUPPORT = 0x20000, // supported, but undocumented
|
|
OVIS_INTERNAL = 0x40000, // internal-only, not available in product release
|
|
OVIS_MASK = 0x60000
|
|
};
|
|
|
|
// Option other attributes : optional
|
|
enum OptionMisc {
|
|
OA_MISC_ALIAS = 0x80000 // An alias option is one that refers to another option or options
|
|
// and its meaning is hard-coded in setAliasOptionVariable().
|
|
};
|
|
|
|
typedef bool OT_BOOL_t;
|
|
typedef int32_t OT_INT32_t;
|
|
typedef uint32_t OT_UINT32_t;
|
|
typedef const char* OT_CSTRING_t;
|
|
typedef unsigned char OT_UCHAR_t;
|
|
|
|
// This must be a POD
|
|
struct OptionDescriptor {
|
|
const char* NameShort; // short option starts with -
|
|
const char* NameLong; // long option starts with --
|
|
uint32_t Info; // defined by above enums
|
|
uint32_t OptionOffset; // member offset to OptionVariable
|
|
int64_t DefaultVal; // default value for option of non-string type
|
|
int64_t ValMin; // (ValMin, ValMax) is the option's Value range
|
|
int64_t ValMax; // for option of non-string type
|
|
const char* DefaultString; // default value for string.
|
|
const char* Description; // Short Description for this option. -h will show this.
|
|
};
|
|
|
|
#define OPTION_sname(o) ((o)->NameShort)
|
|
#define OPTION_lname(o) ((o)->NameLong)
|
|
#define OPTION_type(o) ((o)->Info & OT_MASK)
|
|
#define OPTION_value(o) ((o)->Info & OVA_MASK)
|
|
#define OPTION_form(o) ((o)->Info & OFA_MASK)
|
|
#define OPTION_vis(o) ((o)->Info & OVIS_MASK)
|
|
#define OPTION_info(o) ((o)->Info)
|
|
#define OPTION_offset(o) ((o)->OptionOffset)
|
|
#define OPTION_default(o) ((o)->DefaultVal)
|
|
#define OPTION_min(o) ((o)->ValMin)
|
|
#define OPTION_max(o) ((o)->ValMax)
|
|
#define OPTION_defaultstr(o) ((o)->DefaultString)
|
|
#define OPTION_desc(o) ((o)->Description)
|
|
|
|
// OptionVariables must be a POD
|
|
struct OptionVariables {
|
|
#define OPTION(type, a, sn, ln, var, ideft, imin, imax, sdeft, desc) type##_t var ;
|
|
#define NOPTION(type, a, sn, ln, var, ideft, imin, imax, sdeft, desc)
|
|
#define FLAG(type, a, sn, var, deft, desc) type##_t var ;
|
|
#include "OPTIONS.def"
|
|
#undef OPTION
|
|
#undef NOPTION
|
|
#undef FLAG
|
|
};
|
|
|
|
#define OPTION_valueSeparator(c) (((c) == ' ') || ((c) == '='))
|
|
#define OFFSET(var) ((uint32_t)&(((OptionVariable *)0)->var))
|
|
|
|
|
|
enum OptionIdentifier {
|
|
#define OPTION(type, a, sn, ln, var, ideft, imin, imax, sdeft, desc) OID_##var ,
|
|
#define NOPTION(type, a, sn, ln, var, ideft, imin, imax, sdeft, desc) OID_##var ,
|
|
#define FLAG(type, a, sn, var, deft, desc) OID_##var,
|
|
#include "OPTIONS.def"
|
|
OID_LAST
|
|
#undef OPTION
|
|
#undef NOPTION
|
|
#undef FLAG
|
|
};
|
|
|
|
// Only option that is a RUNTIME option and is not an alias option has an entry in OptionVariables
|
|
#define OPTIONHasOVariable(od) \
|
|
((OPTION_info(od) & (OA_RUNTIME | OA_MISC_ALIAS)) == OA_RUNTIME)
|
|
|
|
// DumpFlags defines the values for oVariables->DumpFlags
|
|
enum DumpFlags {
|
|
DUMP_NONE = 0x00000000, // default
|
|
DUMP_CL = 0x00000001, // CL source
|
|
DUMP_I = 0x00000002, // pre-processed CL source
|
|
DUMP_S = 0x00000004, // x86 assembly text
|
|
DUMP_O = 0x00000008, // x86 object / GPU code object
|
|
DUMP_DLL = 0x00000010, // x86 DLL (.so)
|
|
DUMP_IL = 0x00000020, // per-kernel IL (GPU)
|
|
DUMP_ISA = 0x00000040, // per-kernel assembly text (GPU)
|
|
DUMP_BIF = 0x00000080, // binary for all kernels (GPU)
|
|
DUMP_BC_ORIGINAL = 0x00000100, // input bitcode (generated by clc)
|
|
DUMP_BC_LINKED = 0x00000200, // bitcode after linking and before optimization
|
|
DUMP_BC_OPTIMIZED = 0x00000400, // bitcode after optimization (llvm opt's output)
|
|
DUMP_CGIL = 0x00000800, // output il generated by Codegen (llvm llc's output)
|
|
DUMP_DEBUGIL = 0x00001000, // debug il (from MDParser, dwarf refers to)
|
|
DUMP_SPIRV = 0x00002000, // SPIR-V binary
|
|
DUMP_BC_SPIRV = 0x00004000, // bitcode translated from SPIR-V
|
|
|
|
// For a binary is encrypted, can only dump the following
|
|
DUMP_ENCRYPT = (DUMP_DLL | DUMP_BIF),
|
|
|
|
// For a release product, can only dump the following
|
|
DUMP_PRODUCT_FLAGS = (DUMP_CL | DUMP_I | DUMP_S | DUMP_O | DUMP_DLL |
|
|
DUMP_IL |DUMP_CGIL | DUMP_DEBUGIL |
|
|
DUMP_ISA | DUMP_BIF),
|
|
|
|
DUMP_ALL = 0x00007FFF // Everything
|
|
};
|
|
|
|
enum OptLevelFlags : unsigned char {
|
|
OPT_O0 = '0', // No optimization setting.
|
|
OPT_O1 = '1',
|
|
OPT_O2 = '2',
|
|
OPT_O3 = '3',
|
|
OPT_O4 = '4',
|
|
OPT_O5 = '5',
|
|
OPT_OG = 'g', // g ASCII
|
|
OPT_OS = 's', // s ASCII
|
|
OPT_Error = 0, // Invalid optimization set
|
|
/** Canary Value that guards against enum changes
|
|
* @warning This value cannot be changed without updating the appropriate
|
|
* tests and should NEVER be decreased.
|
|
*/
|
|
optLast = 117
|
|
};
|
|
|
|
class Options {
|
|
public:
|
|
std::string origOptionStr;
|
|
|
|
OptionVariables *oVariables; // pointer to a struct of all option variables
|
|
std::string clcOptions; // options passed into EDG frontend (clc)
|
|
std::vector<std::string> clangOptions; // options passed into Clang frontend
|
|
std::string llvmOptions; // options passed into backend (llvm)
|
|
std::vector<std::string> finalizerOptions; // options passed into finalizer
|
|
|
|
// Given as build option
|
|
int WorkGroupSize[3]; // -1: use default
|
|
int NumAvailGPRs;
|
|
unsigned kernelArgAlign;
|
|
|
|
Options ();
|
|
~Options ();
|
|
|
|
bool isDumpFlagSet(DumpFlags f) {
|
|
return ((oVariables->DumpFlags) & f) && dumpEncrypt(f);
|
|
}
|
|
|
|
// Definition of each entry in flags
|
|
// Note: this is 1-bit entry now, it may need to be expanded to
|
|
// more than 1 bit later.
|
|
enum {
|
|
FLAG_UNSEEN = 0,
|
|
FLAG_SEEN = 1
|
|
};
|
|
|
|
void setFlag(int option_ndx, uint32_t v) {
|
|
int r = option_ndx/32;
|
|
int c = option_ndx%32;
|
|
uint32_t *p = &flags[r];
|
|
uint32_t b = (1 << c);
|
|
v = (v << c);
|
|
*p = ((*p) & (~b)) | v;
|
|
}
|
|
|
|
uint32_t getFlag(int option_ndx) const {
|
|
int r = option_ndx/32;
|
|
int c = option_ndx%32;
|
|
const uint32_t *p = &flags[r];
|
|
uint32_t b = (1 << c);
|
|
return 1 & ((*p) >> c);
|
|
}
|
|
|
|
bool isOptionSeen(int option_ndx) const {
|
|
return (getFlag(option_ndx) == FLAG_SEEN);
|
|
}
|
|
|
|
int getLLVMArgc() { return llvmargc; }
|
|
char** getLLVMArgv() { return llvmargv; }
|
|
void setLLVMArgs (int argc, char** argv) {
|
|
llvmargc = argc;
|
|
llvmargv = argv;
|
|
}
|
|
|
|
void recordMemoryHandle(char* handle) {
|
|
MemoryHandles.push_back(handle);
|
|
}
|
|
|
|
// Do post-parse processing After parsing all options,
|
|
void postParseInit();
|
|
|
|
void setBuildNo(unsigned int bnum) { buildNo = bnum; }
|
|
unsigned int getBuildNo() const { return buildNo; }
|
|
void setCurrKernelName(const char* name) { currKernelName = name; }
|
|
const char* getCurrKernelName() const { return currKernelName; }
|
|
std::string getDumpFileName(const std::string& ext);
|
|
|
|
void setPerBuildInfo(const char* val, int encrypt, bool device);
|
|
bool isCStrOptionsEqual(const char *cs1, const char* cs2) const;
|
|
|
|
|
|
bool useDefaultWGS() { return UseDefaultWGS; }
|
|
void setDefaultWGS(bool V) { UseDefaultWGS = V; }
|
|
|
|
std::string& optionsLog() { return OptionsLog; }
|
|
|
|
// Returns whether this set of options equals to another set of options
|
|
bool equals(const Options& other, bool ignoreClcOptions=false) const;
|
|
|
|
// Set the option variables same as defined in "other"
|
|
bool setOptionVariablesAs(const Options& other);
|
|
|
|
std::string getFinalizerOptions() { return getStringFromStringVec(finalizerOptions); }
|
|
|
|
private:
|
|
std::string fullPath, baseName;
|
|
long basename_max;
|
|
std::string OptionsLog;
|
|
|
|
// One bit for each flag.
|
|
const int flagsSize;
|
|
uint32_t flags[(OID_LAST + 31)/32];
|
|
|
|
int llvmargc;
|
|
char** llvmargv;
|
|
|
|
// buildNo is a unique number for each device build, save it here so that
|
|
// dumping can use it in its file names.
|
|
//
|
|
// Note that buildNo, dumpFileRoot, and encryptCode are valid only during the lifetime
|
|
// of a device build.
|
|
unsigned int buildNo;
|
|
std::string dumpFileRoot;
|
|
const char* currKernelName;
|
|
int encryptCode;
|
|
|
|
std::vector<char*> MemoryHandles;
|
|
|
|
bool UseDefaultWGS;
|
|
|
|
bool dumpEncrypt(DumpFlags f) {
|
|
return ((encryptCode == 0) || // return true if not encrypted
|
|
(f & DUMP_ENCRYPT));
|
|
}
|
|
|
|
std::string getStringFromStringVec(std::vector<std::string>& stringVec);
|
|
void setDumpFileName(const char* val);
|
|
|
|
public:
|
|
LibrarySelector libraryType_;
|
|
std::string sourceFileName_;
|
|
};
|
|
|
|
OptionDescriptor* getOptDescTable();
|
|
bool init();
|
|
bool teardown();
|
|
bool parseAllOptions(std::string& options, Options& Opts,
|
|
bool linkOptsOnly=false);
|
|
inline bool parseLinkOptions(std::string& options, Options& Opts) {
|
|
return parseAllOptions(options, Opts, true/*linkOptsOnly*/);
|
|
}
|
|
|
|
|
|
} // option
|
|
|
|
} // amd
|
|
|
|
#endif // _UTILS_OPTIONS_HPP_
|