blob: 0ffff1c3d9013979f8f18cc0cacd0b05bd7d919b [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- subzero/src/IceGlobalContext.h - Global context defs -----*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares aspects of the compilation that persist across
11// multiple functions.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H
16#define SUBZERO_SRC_ICEGLOBALCONTEXT_H
17
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070018#include <memory>
19
Jim Stichnothf7c9a142014-04-29 10:52:43 -070020#include "llvm/Support/Allocator.h"
21#include "llvm/Support/raw_ostream.h"
22
23#include "IceDefs.h"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070024#include "IceIntrinsics.h"
Matt Wala1bd2fce2014-08-08 14:02:09 -070025#include "IceRNG.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070026#include "IceTypes.h"
27
28namespace Ice {
29
Jim Stichnoth989a7032014-08-08 10:13:44 -070030class ClFlags;
31
Jim Stichnoth18735602014-09-16 19:59:35 -070032// This class collects rudimentary statistics during translation.
33class CodeStats {
34public:
35 CodeStats()
36 : InstructionsEmitted(0), RegistersSaved(0), FrameBytes(0), Spills(0),
37 Fills(0) {}
38 void reset() { *this = CodeStats(); }
39 void updateEmitted(uint32_t InstCount) { InstructionsEmitted += InstCount; }
40 void updateRegistersSaved(uint32_t Num) { RegistersSaved += Num; }
41 void updateFrameBytes(uint32_t Bytes) { FrameBytes += Bytes; }
42 void updateSpills() { ++Spills; }
43 void updateFills() { ++Fills; }
44 void dump(const IceString &Name, Ostream &Str) {
45 Str << "|" << Name << "|Inst Count |" << InstructionsEmitted << "\n";
46 Str << "|" << Name << "|Regs Saved |" << RegistersSaved << "\n";
47 Str << "|" << Name << "|Frame Bytes |" << FrameBytes << "\n";
48 Str << "|" << Name << "|Spills |" << Spills << "\n";
49 Str << "|" << Name << "|Fills |" << Fills << "\n";
50 Str << "|" << Name << "|Spills+Fills|" << Spills + Fills << "\n";
51 }
52
53private:
54 uint32_t InstructionsEmitted;
55 uint32_t RegistersSaved;
56 uint32_t FrameBytes;
57 uint32_t Spills;
58 uint32_t Fills;
59};
60
Jim Stichnothf7c9a142014-04-29 10:52:43 -070061// TODO: Accesses to all non-const fields of GlobalContext need to
62// be synchronized, especially the constant pool, the allocator, and
63// the output streams.
64class GlobalContext {
65public:
66 GlobalContext(llvm::raw_ostream *OsDump, llvm::raw_ostream *OsEmit,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070067 VerboseMask Mask, TargetArch Arch, OptLevel Opt,
Jim Stichnoth989a7032014-08-08 10:13:44 -070068 IceString TestPrefix, const ClFlags &Flags);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070069 ~GlobalContext();
70
71 // Returns true if any of the specified options in the verbose mask
72 // are set. If the argument is omitted, it checks if any verbose
Jim Stichnothc4554d72014-09-30 16:49:38 -070073 // options at all are set.
74 bool isVerbose(VerboseMask Mask = IceV_All) const { return VMask & Mask; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070075 void setVerbose(VerboseMask Mask) { VMask = Mask; }
76 void addVerbose(VerboseMask Mask) { VMask |= Mask; }
77 void subVerbose(VerboseMask Mask) { VMask &= ~Mask; }
78
Jim Stichnoth78282f62014-07-27 23:14:00 -070079 Ostream &getStrDump() { return *StrDump; }
80 Ostream &getStrEmit() { return *StrEmit; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070081
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070082 TargetArch getTargetArch() const { return Arch; }
83 OptLevel getOptLevel() const { return Opt; }
84
Jim Stichnothf7c9a142014-04-29 10:52:43 -070085 // When emitting assembly, we allow a string to be prepended to
86 // names of translated functions. This makes it easier to create an
87 // execution test against a reference translator like llc, with both
88 // translators using the same bitcode as input.
89 IceString getTestPrefix() const { return TestPrefix; }
90 IceString mangleName(const IceString &Name) const;
91
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070092 // The purpose of HasEmitted is to add a header comment at the
93 // beginning of assembly code emission, doing it once per file
94 // rather than once per function.
95 bool testAndSetHasEmittedFirstMethod() {
96 bool HasEmitted = HasEmittedFirstMethod;
97 HasEmittedFirstMethod = true;
98 return HasEmitted;
99 }
100
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700101 // Manage Constants.
102 // getConstant*() functions are not const because they might add
103 // something to the constant pool.
Jan Voungbc004632014-09-16 15:09:10 -0700104 Constant *getConstantInt32(Type Ty, uint32_t ConstantInt32);
105 Constant *getConstantInt64(Type Ty, uint64_t ConstantInt64);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700106 Constant *getConstantFloat(float Value);
107 Constant *getConstantDouble(double Value);
108 // Returns a symbolic constant.
109 Constant *getConstantSym(Type Ty, int64_t Offset, const IceString &Name = "",
110 bool SuppressMangling = false);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700111 // Returns an undef.
112 Constant *getConstantUndef(Type Ty);
113 // Returns a zero value.
114 Constant *getConstantZero(Type Ty);
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700115 // getConstantPool() returns a copy of the constant pool for
116 // constants of a given type.
117 ConstantList getConstantPool(Type Ty) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700118
Jim Stichnoth989a7032014-08-08 10:13:44 -0700119 const ClFlags &getFlags() const { return Flags; }
120
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700121 // Allocate data of type T using the global allocator.
122 template <typename T> T *allocate() { return Allocator.Allocate<T>(); }
123
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700124 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
125
Matt Wala1bd2fce2014-08-08 14:02:09 -0700126 // TODO(wala,stichnot): Make the RNG play nicely with multithreaded
127 // translation.
128 RandomNumberGenerator &getRNG() { return RNG; }
129
Jim Stichnoth18735602014-09-16 19:59:35 -0700130 // Reset stats at the beginning of a function.
131 void resetStats() { StatsFunction.reset(); }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700132 void dumpStats(const IceString &Name, bool Final = false);
Jim Stichnoth18735602014-09-16 19:59:35 -0700133 void statsUpdateEmitted(uint32_t InstCount) {
134 StatsFunction.updateEmitted(InstCount);
135 StatsCumulative.updateEmitted(InstCount);
136 }
137 void statsUpdateRegistersSaved(uint32_t Num) {
138 StatsFunction.updateRegistersSaved(Num);
139 StatsCumulative.updateRegistersSaved(Num);
140 }
141 void statsUpdateFrameBytes(uint32_t Bytes) {
142 StatsFunction.updateFrameBytes(Bytes);
143 StatsCumulative.updateFrameBytes(Bytes);
144 }
145 void statsUpdateSpills() {
146 StatsFunction.updateSpills();
147 StatsCumulative.updateSpills();
148 }
149 void statsUpdateFills() {
150 StatsFunction.updateFills();
151 StatsCumulative.updateFills();
152 }
153
Jim Stichnothc4554d72014-09-30 16:49:38 -0700154 static TimerIdT getTimerID(const IceString &Name);
155 void pushTimer(TimerIdT ID);
156 void popTimer(TimerIdT ID);
157 void dumpTimers();
158
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700159private:
Jim Stichnoth78282f62014-07-27 23:14:00 -0700160 Ostream *StrDump; // Stream for dumping / diagnostics
161 Ostream *StrEmit; // Stream for code emission
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700162
163 llvm::BumpPtrAllocator Allocator;
164 VerboseMask VMask;
Jim Stichnotha18cc9c2014-09-30 19:10:22 -0700165 std::unique_ptr<class ConstantPool> ConstPool;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700166 Intrinsics IntrinsicsInfo;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700167 const TargetArch Arch;
168 const OptLevel Opt;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700169 const IceString TestPrefix;
Jim Stichnoth989a7032014-08-08 10:13:44 -0700170 const ClFlags &Flags;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700171 bool HasEmittedFirstMethod;
Matt Wala1bd2fce2014-08-08 14:02:09 -0700172 RandomNumberGenerator RNG;
Jim Stichnoth18735602014-09-16 19:59:35 -0700173 CodeStats StatsFunction;
174 CodeStats StatsCumulative;
Jim Stichnotha18cc9c2014-09-30 19:10:22 -0700175 std::unique_ptr<class TimerStack> Timers;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700176 GlobalContext(const GlobalContext &) = delete;
177 GlobalContext &operator=(const GlobalContext &) = delete;
Jim Stichnoth217dc082014-07-11 14:06:55 -0700178
179 // Private helpers for mangleName()
180 typedef llvm::SmallVector<char, 32> ManglerVector;
181 void incrementSubstitutions(ManglerVector &OldName) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700182};
183
Jim Stichnothc4554d72014-09-30 16:49:38 -0700184// Helper class to push and pop a timer marker. The constructor
185// pushes a marker, and the destructor pops it. This is for
186// convenient timing of regions of code.
187class TimerMarker {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700188 TimerMarker(const TimerMarker &) = delete;
189 TimerMarker &operator=(const TimerMarker &) = delete;
Jim Stichnothc4554d72014-09-30 16:49:38 -0700190
191public:
192 TimerMarker(TimerIdT ID, GlobalContext *Ctx)
193 : ID(ID), Ctx(Ctx), Active(Ctx->getFlags().SubzeroTimingEnabled) {
194 if (Active)
195 Ctx->pushTimer(ID);
196 }
197 ~TimerMarker() {
198 if (Active)
199 Ctx->popTimer(ID);
200 }
201
202private:
203 TimerIdT ID;
204 GlobalContext *const Ctx;
205 const bool Active;
206};
207
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700208} // end of namespace Ice
209
210#endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H