Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: src/IceGlobalContext.cpp

Issue 610813002: Subzero: Rewrite the pass timing infrastructure. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Bug fixes and performance improvements Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceGlobalContext.cpp
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 319e18a9d6a3c6ecac74d7bc3454b44eed6bbaad..52a943ff3de60b88e87ce6a5a8d4d3412881c52d 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -115,6 +115,98 @@ public:
UndefPool Undefs;
};
+class TimerStack {
+ TimerStack(const TimerStack &) LLVM_DELETED_FUNCTION;
+ TimerStack &operator=(const TimerStack &) LLVM_DELETED_FUNCTION;
+
+public:
+ TimerStack(const IceString &TopLevelName)
+ : FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp),
+ StateChanges(0) {
+ push(TopLevelName);
+ }
+ void push(const IceString &Name) {
+ update();
+ Stack.push_back(Name);
+ // Construct the new node's recursive name by appending .Name to
+ // the previous top-of-stack's recursive name.
+ IceString Prefix = "";
+ if (!FullNames.empty())
+ Prefix = FullNames.back() + ".";
+ FullNames.push_back(Prefix + Name);
Karl 2014/09/29 16:55:07 Minor nit. There is a lot of string building going
Jim Stichnoth 2014/09/30 17:50:50 Good point, and it does turn into a real performan
+ }
+ void pop(const IceString &Name) {
+ update();
+ assert(!Stack.empty());
+ assert(Stack.back() == Name);
+ (void)Name;
+ Stack.pop_back();
+ FullNames.pop_back();
+ }
+ void dump(Ostream &Str);
+
+private:
+ typedef std::map<IceString, double> MapType;
Karl 2014/09/29 16:55:07 Using string as the key can be quite expensive. Co
Jim Stichnoth 2014/09/30 17:50:50 Done, see the comment above.
+ void update();
+ void dumpHelper(Ostream &Str, const MapType &Map, double TotalTime);
+ static double timestamp() {
+ // TODO: Implement in terms of std::chrono for C++11.
+ return llvm::TimeRecord::getCurrentTime(false).getWallTime();
+ }
+ const double FirstTimestamp;
+ volatile double LastTimestamp;
+ std::vector<IceString> Stack;
+ std::vector<IceString> FullNames;
+ MapType RecursiveTime;
+ MapType LeafTime;
+ uint64_t StateChanges;
+};
+
+void TimerStack::update() {
+ ++StateChanges;
+ // Whenever the stack is about to change, we grab the time delta
+ // since the last change and add it to all active recursive elements
+ // and to the non-recursive element for the top of the stack.
+ double Current = timestamp();
+ double Delta = Current - LastTimestamp;
+ LastTimestamp = Current;
+ for (size_t i = 0; i < FullNames.size(); ++i) {
+ RecursiveTime[FullNames[i]] += Delta;
+ }
+ if (!Stack.empty()) {
+ LeafTime[Stack.back()] += Delta;
+ }
+}
+
+void TimerStack::dumpHelper(Ostream &Str, const MapType &Map,
+ double TotalTime) {
+ // Dump the items in reverse order of their time contribution.
+ typedef std::multimap<double, IceString> RMapType;
+ RMapType MultiMap;
+ for (MapType::const_iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
+ MultiMap.insert(std::make_pair(I->second, I->first));
+ }
+ for (RMapType::const_reverse_iterator I = MultiMap.rbegin(),
+ E = MultiMap.rend();
+ I != E; ++I) {
+ char buf[80];
+ snprintf(buf, llvm::array_lengthof(buf), " %10.6f (%4.1f%%): ", I->first,
+ I->first * 100 / TotalTime);
+ Str << buf << I->second << "\n";
+ }
+}
+
+void TimerStack::dump(Ostream &Str) {
+ update();
+ double TotalTime = LastTimestamp - FirstTimestamp;
+ assert(TotalTime);
+ Str << "Recursive function times:\n";
+ dumpHelper(Str, RecursiveTime, TotalTime);
+ Str << "Non-recursive function times:\n";
+ dumpHelper(Str, LeafTime, TotalTime);
+ Str << "Number of timer updates: " << StateChanges << "\n";
+}
+
GlobalContext::GlobalContext(llvm::raw_ostream *OsDump,
llvm::raw_ostream *OsEmit, VerboseMask Mask,
TargetArch Arch, OptLevel Opt,
@@ -122,7 +214,7 @@ GlobalContext::GlobalContext(llvm::raw_ostream *OsDump,
: StrDump(OsDump), StrEmit(OsEmit), VMask(Mask),
ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt),
TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false),
- RNG("") {}
+ RNG(""), Timers(new TimerStack("main")) {}
// Scan a string for S[0-9A-Z]*_ patterns and replace them with
// S<num>_ where <num> is the next base-36 value. If a type name
@@ -384,6 +476,12 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const {
llvm_unreachable("Unknown type");
}
+void GlobalContext::pushTimer(const IceString &Name) {
+ Timers.get()->push(Name);
+}
+
+void GlobalContext::popTimer(const IceString &Name) { Timers.get()->pop(Name); }
+
void GlobalContext::dumpStats(const IceString &Name, bool Final) {
if (Flags.DumpStats) {
if (Final) {
@@ -395,12 +493,6 @@ void GlobalContext::dumpStats(const IceString &Name, bool Final) {
}
}
-void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const {
- if (Ctx->isVerbose(IceV_Timing)) {
- // Prefixing with '#' allows timing strings to be included
- // without error in textual assembly output.
- Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n";
- }
-}
+void GlobalContext::dumpTimers() { Timers.get()->dump(getStrDump()); }
} // end of namespace Ice

Powered by Google App Engine
This is Rietveld 408576698