diff --git a/CMakeLists.txt b/CMakeLists.txt index 7172a3f6..0d84e9b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,11 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(STA_HOME ${PROJECT_SOURCE_DIR}) message(STATUS "STA version: ${PROJECT_VERSION}") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(GetGitRevisionDescription) +get_git_head_revision(GIT_REFSPEC STA_GIT_SHA1) +message(STATUS "STA git sha: ${STA_GIT_SHA1}") + # Default to bulding optimnized/release executable. if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RELEASE) diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..8ab03bc5 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,168 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# git_local_changes() +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + diff-index --quiet HEAD -- + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} "CLEAN" PARENT_SCOPE) + else() + set(${_var} "DIRTY" PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 00000000..6d8b708e --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,41 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/graph/Graph.cc b/graph/Graph.cc index 9bd5cabd..499033c1 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -51,7 +51,6 @@ Graph::Graph(StaState *sta, slew_tr_count_(slew_tr_count), have_arc_delays_(have_arc_delays), ap_count_(ap_count), - float_pool_(nullptr), width_check_annotations_(nullptr), period_check_annotations_(nullptr) { @@ -63,9 +62,8 @@ Graph::~Graph() delete edges_; deleteSlewPools(); deleteArcDelayPools(); - delete width_check_annotations_; - delete period_check_annotations_; - delete float_pool_; + removeWidthCheckAnnotations(); + removePeriodCheckAnnotations(); } void @@ -1010,7 +1008,7 @@ Graph::setWidthCheckAnnotation(const Pin *pin, float *widths = width_check_annotations_->findKey(pin); if (widths == nullptr) { int width_count = TransRiseFall::index_count * ap_count_; - widths = makeFloats(width_count); + widths = new float[width_count]; // Use negative (illegal) width values to indicate unannotated checks. for (int i = 0; i < width_count; i++) widths[i] = -1; @@ -1024,11 +1022,10 @@ void Graph::removeWidthCheckAnnotations() { if (width_check_annotations_) { - int width_count = TransRiseFall::index_count * ap_count_; WidthCheckAnnotations::Iterator check_iter(width_check_annotations_); while (check_iter.hasNext()) { float *widths = check_iter.next(); - deleteFloats(widths, width_count); + delete [] widths; } delete width_check_annotations_; width_check_annotations_ = nullptr; @@ -1064,9 +1061,9 @@ Graph::setPeriodCheckAnnotation(const Pin *pin, period_check_annotations_ = new PeriodCheckAnnotations; float *periods = period_check_annotations_->findKey(pin); if (periods == nullptr) { - periods = makeFloats(ap_count_); + periods = new float[ap_count_]; // Use negative (illegal) period values to indicate unannotated checks. - for (DcalcAPIndex i = 0; i < ap_count_; i++) + for (int i = 0; i < ap_count_; i++) periods[i] = -1; (*period_check_annotations_)[pin] = periods; } @@ -1079,7 +1076,7 @@ Graph::removePeriodCheckAnnotations() if (period_check_annotations_) { for (auto pin_floats : *period_check_annotations_) { float *periods = pin_floats.second; - deleteFloats(periods, ap_count_); + delete [] periods; } delete period_check_annotations_; period_check_annotations_ = nullptr; @@ -1103,20 +1100,6 @@ Graph::removeDelaySlewAnnotations() removePeriodCheckAnnotations(); } -float * -Graph::makeFloats(ObjectIndex count) -{ - if (float_pool_ == nullptr) - float_pool_ = new Pool(100); - return float_pool_->makeObjects(count); -} - -void -Graph::deleteFloats(float *floats, ObjectIndex count) -{ - float_pool_->deleteObjects(floats, count); -} - //////////////////////////////////////////////////////////////// // // Vertex diff --git a/graph/Graph.hh b/graph/Graph.hh index c230f24f..68a83ccd 100644 --- a/graph/Graph.hh +++ b/graph/Graph.hh @@ -216,9 +216,6 @@ protected: void deleteOutEdge(Vertex *vertex, Edge *edge); void removeDelays(); - float *makeFloats(ObjectIndex count); - void deleteFloats(float *floats, - ObjectIndex count); void removeDelayAnnotated(Edge *edge); // User defined predicate to filter graph edges for liberty timing arcs. virtual bool filterEdge(TimingArcSet *) const { return true; } @@ -240,7 +237,6 @@ protected: DelayPoolSeq slew_pools_; // [ap_index][tr_index][vertex_index] VertexIndex slew_count_; DelayPoolSeq arc_delays_; // [ap_index][edge_arc_index] - Pool *float_pool_; // Sdf width check annotations. WidthCheckAnnotations *width_check_annotations_; // Sdf period check annotations. diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index ecc6b360..a681f967 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -1167,7 +1167,9 @@ ConcreteNetwork::replaceCell(Instance *inst, int port_count = ccell->portBitCount(); ConcreteInstance *cinst = reinterpret_cast(inst); ConcretePin **pins = cinst->pins_; - ConcretePin **rpins = new ConcretePin*[port_count]{nullptr}; + ConcretePin **rpins = new ConcretePin*[port_count]; + for (int i = 0; i < port_count; i++) + rpins[i] = nullptr; for (int i = 0; i < port_count; i++) { ConcretePin *cpin = pins[i]; if (cpin) { @@ -1489,8 +1491,11 @@ void ConcreteInstance::initPins() { int pin_count = reinterpret_cast(cell_)->portBitCount(); - if (pin_count) - pins_ = new ConcretePin*[pin_count]{nullptr}; + if (pin_count) { + pins_ = new ConcretePin*[pin_count]; + for (int i = 0; i < pin_count; i++) + pins_[i] = nullptr; + } else pins_ = nullptr; } diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index 6ac1bf6d..5b34e075 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -1071,7 +1071,9 @@ ConcreteParasitics::makePiElmore(const Pin *drvr_pin, if (parasitics == nullptr) { int ap_count = corners_->parasiticAnalysisPtCount(); int ap_tr_count = ap_count * TransRiseFall::index_count; - parasitics = new ConcreteParasitic*[ap_tr_count]{nullptr}; + parasitics = new ConcreteParasitic*[ap_tr_count]; + for (int i = 0; i < ap_tr_count; i++) + parasitics[i] = nullptr; drvr_parasitic_map_[drvr_pin] = parasitics; } int ap_tr_index = parasiticAnalysisPtIndex(ap, tr); @@ -1189,7 +1191,9 @@ ConcreteParasitics::makePiPoleResidue(const Pin *drvr_pin, if (parasitics == nullptr) { int ap_count = corners_->parasiticAnalysisPtCount(); int ap_tr_count = ap_count * TransRiseFall::index_count; - parasitics = new ConcreteParasitic*[ap_tr_count]{nullptr}; + parasitics = new ConcreteParasitic*[ap_tr_count]; + for (int i = 0; i < ap_tr_count; i++) + parasitics[i] = nullptr; drvr_parasitic_map_[drvr_pin] = parasitics; } int ap_tr_index = parasiticAnalysisPtIndex(ap, tr); @@ -1312,7 +1316,9 @@ ConcreteParasitics::makeParasiticNetwork(const Net *net, ConcreteParasiticNetwork **parasitics = parasitic_network_map_.findKey(net); if (parasitics == nullptr) { int ap_count = corners_->parasiticAnalysisPtCount(); - parasitics = new ConcreteParasiticNetwork*[ap_count]{nullptr}; + parasitics = new ConcreteParasiticNetwork*[ap_count]; + for (int i = 0; i < ap_count; i++) + parasitics[i] = nullptr; parasitic_network_map_[net] = parasitics; } int ap_index = ap->index(); diff --git a/tcl/Sdc.tcl b/tcl/Sdc.tcl index 8bfa9893..c9ac24c0 100644 --- a/tcl/Sdc.tcl +++ b/tcl/Sdc.tcl @@ -197,7 +197,7 @@ define_cmd_args "set_units" \ # It merely checks that the library units are the same as the # units in the set_units command. proc set_units { args } { - parse_key_args "set_cmd_units" args \ + parse_key_args "set_units" args \ keys {-capacitance -resistance -time -voltage -current -power} flags {} if { [llength $args] != 0 } { cmd_usage_error "set_units" diff --git a/tcl/Splash.tcl b/tcl/Splash.tcl index 177129bd..2ae6a034 100644 --- a/tcl/Splash.tcl +++ b/tcl/Splash.tcl @@ -25,12 +25,12 @@ namespace eval sta { define_cmd_args show_splash {} proc show_splash {} { - puts {OpenSTA Copyright (c) 2018, Parallax Software, Inc. + puts "OpenSTA [sta::version] [string range [sta::git_sha1] 0 9] Copyright (c) 2019, Parallax Software, Inc. License GPLv3: GNU GPL version 3 This is free software, and you are free to change and redistribute it under certain conditions; type `show_copying' for details. -This program comes with ABSOLUTELY NO WARRANTY; for details type `show_warranty'.} +This program comes with ABSOLUTELY NO WARRANTY; for details type `show_warranty'." } define_cmd_args show_warranty {} diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 6fa9b6ce..37085132 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -1909,6 +1909,12 @@ version() return STA_VERSION; } +const char * +git_sha1() +{ + return STA_GIT_SHA1; +} + void redirect_file_begin(const char *filename) { diff --git a/util/StaConfig.hh.cmake b/util/StaConfig.hh.cmake index c162013f..395df2a2 100644 --- a/util/StaConfig.hh.cmake +++ b/util/StaConfig.hh.cmake @@ -1,5 +1,7 @@ #define STA_VERSION "${STA_VERSION}" +#define STA_GIT_SHA1 "${STA_GIT_SHA1}" + #define ZLIB ${ZLIB} #define CUDD ${CUDD}