|
67 | 67 | #include <iostream>
|
68 | 68 | #endif
|
69 | 69 |
|
| 70 | +// for debug trace in GCC |
| 71 | +#if !defined(NDEBUG) && defined(__GNUC__) && !(defined(__ANDROID__) || defined(ANDROID)) |
| 72 | +#include <execinfo.h> |
| 73 | +#include <map> |
| 74 | +#include <sstream> |
| 75 | +#endif |
| 76 | + |
70 | 77 | // #define XBYAK_DISABLE_AVX512
|
71 | 78 |
|
72 | 79 | #if !defined(XBYAK_USE_MMAP_ALLOCATOR) && !defined(XBYAK_DONT_USE_MMAP_ALLOCATOR)
|
@@ -2097,12 +2104,14 @@ class CodeGenerator : public CodeArray {
|
2097 | 2104 | }
|
2098 | 2105 | void opRR(const Reg& reg1, const Reg& reg2, uint64_t type, int code)
|
2099 | 2106 | {
|
| 2107 | + debug_trace(); |
2100 | 2108 | bool rex2 = rex(reg2, reg1, type);
|
2101 | 2109 | writeCode(type, reg1, code, rex2);
|
2102 | 2110 | setModRM(3, reg1.getIdx(), reg2.getIdx());
|
2103 | 2111 | }
|
2104 | 2112 | void opMR(const Address& addr, const Reg& r, uint64_t type, int code, uint64_t type2 = 0, int code2 = NONE)
|
2105 | 2113 | {
|
| 2114 | + debug_trace(); |
2106 | 2115 | if (code2 == NONE) code2 = code;
|
2107 | 2116 | if (type2 && opROO(Reg(), addr, r, type2, code2)) return;
|
2108 | 2117 | if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP)
|
@@ -2404,6 +2413,7 @@ class CodeGenerator : public CodeArray {
|
2404 | 2413 | if (bit == 16 || bit == BIT) {
|
2405 | 2414 | if (bit == 16) db(0x66);
|
2406 | 2415 | if (op.isREG()) {
|
| 2416 | + debug_trace(); |
2407 | 2417 | if (op.getReg().getIdx() >= 8) db(0x41);
|
2408 | 2418 | db(alt | (op.getIdx() & 7));
|
2409 | 2419 | return;
|
@@ -2494,6 +2504,7 @@ class CodeGenerator : public CodeArray {
|
2494 | 2504 | }
|
2495 | 2505 | void opVex(const Reg& r, const Operand *p1, const Operand& op2, uint64_t type, int code, int imm8 = NONE)
|
2496 | 2506 | {
|
| 2507 | + debug_trace(); |
2497 | 2508 | if (op2.isMEM()) {
|
2498 | 2509 | Address addr = op2.getAddress();
|
2499 | 2510 | const RegExp& regExp = addr.getRegExp();
|
@@ -3047,6 +3058,35 @@ class CodeGenerator : public CodeArray {
|
3047 | 3058 | opRO(static_cast<const Reg&>(*p1), *p2, 0, 0x86 | (p1->isBit(8) ? 0 : 1), (p1->isREG() && (p1->getBit() == p2->getBit())));
|
3048 | 3059 | }
|
3049 | 3060 |
|
| 3061 | +#if !defined(NDEBUG) && defined(__GNUC__) && !(defined(__ANDROID__) || defined(ANDROID)) |
| 3062 | + std::map<size_t, std::string> debug_traces; |
| 3063 | + void debug_trace() { |
| 3064 | + static bool enable_trace = std::getenv("ONEDNN_JIT_DUMP") && atoi(std::getenv("ONEDNN_JIT_DUMP")) != 0; |
| 3065 | + if (!enable_trace) |
| 3066 | + return; |
| 3067 | + |
| 3068 | + void *array[8]; |
| 3069 | + int size = backtrace(array, 8); |
| 3070 | + char **strings = backtrace_symbols(array, size); |
| 3071 | + std::stringstream ss; |
| 3072 | + // skip first 2 frame (backtrace,trace_code) |
| 3073 | + for(int i = 2; i < size; ++i) ss << "," << strings[i]; |
| 3074 | + auto offset = getSize(); |
| 3075 | + if (debug_traces.count(offset)) { |
| 3076 | + debug_traces[offset] += ss.str(); |
| 3077 | + } else { |
| 3078 | + debug_traces[offset] = ss.str(); |
| 3079 | + } |
| 3080 | + free(strings); |
| 3081 | + } |
| 3082 | + std::map<size_t, std::string> get_debug_traces() const { |
| 3083 | + return debug_traces; |
| 3084 | + } |
| 3085 | +#else |
| 3086 | + void debug_trace() {} |
| 3087 | + std::map<size_t, std::string> get_debug_traces() const { return {}; } |
| 3088 | +#endif |
| 3089 | + |
3050 | 3090 | #ifndef XBYAK_DISABLE_SEGMENT
|
3051 | 3091 | void push(const Segment& seg)
|
3052 | 3092 | {
|
|
0 commit comments