* ./katabatic:

- Change: In KatabaticEngine, the containers used to store the "nets to
        route" is changed from a vector<> to a set<> sorted by the Nets names.
        Uses more memory but allows much faster Net deletion.
    - New: In _loadNetGlobalRouting(Net*), detect non-routed Nets. A Net is
        considered as unrouted if it's 10 first RoutingPads have no slave
        Segment. The Net is withdrawn from the set of Nets to route.
    - Bug: In GCellConfiguration::_GCell_1G_1L1(), correctly compute the
        access flag passed to _GCell_rp_Access().
    - Change: In AutoContact::restrictConstraintBox() adds "warnOnError"
        parameter to shut down warnings.
    - New: KatabaticEngine::_computeNetConstraints() now also returns a set<>
        of segments on which constraints are incompatibles. All the NetConstraints
        related functions are modificateds accordingly.
    - Change: In KatabaticEngine::_loadNetGlobalRouting(), create dogleg
        on overconstrained Segments computed by a call to _computeNetConstraints().
          Overconstraineds Segments can occurs when a global is directly
        connecting two punctual RoutingPads (see "ieee_division").
          As a side effect, and to avoid looping each Net is revalidated
        *before* making any dogleg. So Nets are revalidated one by one instead
        of alltogether.
    - Change: In AutoSegment::_toConstraintAxis(), do nothing if constraint
        interval is empty.
This commit is contained in:
Jean-Paul Chaput 2010-05-11 11:04:23 +00:00
parent e32f8c72de
commit 966de8279c
14 changed files with 189 additions and 120 deletions

View File

@ -2306,7 +2306,7 @@ namespace Katabatic {
//if ( _fixed ) return Box(getCenter());
Component* component = getAnchor();
if ( !component ) return _gcell->getBoundingBox ();
if ( component == NULL ) return _gcell->getBoundingBox ();
DbU::Unit xMin;
DbU::Unit xMax;
@ -2576,50 +2576,52 @@ namespace Katabatic {
}
void AutoContact::restrictConstraintBox ( DbU::Unit constraintMin
bool AutoContact::restrictConstraintBox ( DbU::Unit constraintMin
, DbU::Unit constraintMax
, unsigned int direction )
, unsigned int direction
, bool warnOnError )
{
if ( direction & Constant::Horizontal ) {
if ( (constraintMin > getCBYMax()) || (constraintMax < getCBYMin()) ) {
if ( Session::getDemoMode() ) return;
if ( (constraintMin > getCBYMax()) or (constraintMax < getCBYMin()) ) {
if ( Session::getDemoMode() or not warnOnError ) return false;
cerr << Error ( "Incompatible DY restriction on %s", _getString().c_str() ) << endl;
if ( constraintMin > getCBYMax() )
cerr << Error ( "(constraintMin > CBYMax : %lf > %lf)"
cerr << Error ( "(constraintMin > CBYMax : %.2lf > %.2lf)"
, DbU::getLambda(constraintMin)
, DbU::getLambda(getCBYMax()) )
<< endl;
if ( constraintMax < getCBYMin() )
cerr << Error ( "(constraintMax < CBYMin : %lf < %lf)"
cerr << Error ( "(constraintMax < CBYMin : %.2lf < %.2lf)"
, DbU::getLambda(constraintMax)
, DbU::getLambda(getCBYMin()) )
<< endl;
return;
return false;
}
setCBYMin ( max(getCBYMin(),constraintMin) );
setCBYMax ( min(getCBYMax(),constraintMax) );
} else if ( direction & Constant::Vertical ) {
if ( (constraintMin > getCBXMax()) || (constraintMax < getCBXMin()) ) {
if ( Session::getDemoMode() ) return;
if ( Session::getDemoMode() or not warnOnError ) return false;
cerr << Error ( "Incompatible DX restriction on %s", _getString().c_str() ) << endl;
if ( constraintMin > getCBXMax() )
cerr << Error ( "(constraintMin > CBXMax : %lf > %lf)"
cerr << Error ( "(constraintMin > CBXMax : %.2lf > %.2lf)"
, DbU::getLambda(constraintMin)
, DbU::getLambda(getCBXMax()) )
<< endl;
if ( constraintMax < getCBXMin() )
cerr << Error ( "(constraintMax < CBXMin : %lf < %lf)"
cerr << Error ( "(constraintMax < CBXMin : %.2lf < %.2lf)"
, DbU::getLambda(constraintMax)
, DbU::getLambda(getCBXMin()) )
<< endl;
return;
return false;
}
setCBXMin ( max(getCBXMin(),constraintMin) );
setCBXMax ( min(getCBXMax(),constraintMax) );
}
ltrace(110) << "restrictConstraintBox() - " << this << " " << getConstraintBox() << endl;
return true;
}

View File

@ -535,6 +535,9 @@ namespace Katabatic {
getConstraints ( constraintMin, constraintMax );
// Empty constraint interval: ignore.
if ( constraintMin > constraintMax ) return false;
if ( allowOutsideGCell() ) {
// Ugly: hard-wired value of the track spacing.
constraintMin -= DbU::lambda(5.0) * 8;

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
@ -280,12 +280,28 @@ namespace Katabatic {
constraintMin = contact->getCBXMin();
constraintMax = contact->getCBXMax();
ltrace(148) << "Source constraints: " << contact << " ["
<< DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]"
<< endl;
contact = getAutoTarget();
constraintMin = max ( constraintMin, contact->getCBXMin() );
constraintMax = min ( constraintMax, contact->getCBXMax() );
ltrace(148) << "Merge with target constraints: " << contact << " ["
<< DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]"
<< endl;
constraintMin = max ( constraintMin, getUserConstraints().getVMin() );
constraintMax = min ( constraintMax, getUserConstraints().getVMax() );
ltrace(148) << "Merge with user constraints: " << getUserConstraints() << " ["
<< DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]"
<< endl;
return true;
}

View File

@ -711,8 +711,12 @@ namespace Katabatic {
if ( rpNets.size() < 8 ) return;
cerr << "[WARNING] " << this << " has " << rps.size() << " terminals (h:"
<< _hsegments.size() << ")" << endl;
// cerr << Warning("%s has %ud terminals (h:%ud, v:%ud)"
// ,getString(this).c_str()
// ,rps.size()
// ,_hsegments.size()
// ,_vsegments.size()
// ) << endl;
AutoSegment* segment;
while ( stepDesaturate ( 1, globalNets, segment, true ) ) {

View File

@ -111,7 +111,7 @@ namespace Katabatic {
void GraphicKatabaticEngine::run ()
{
static vector<Net*> routingNets;
static KatabaticEngine::NetSet routingNets;
emit cellPreModificated ();

View File

@ -55,16 +55,6 @@ namespace {
using namespace Hurricane;
struct NetCompareByName {
inline bool operator() ( const Net* lhs, const Net* rhs ) const;
};
inline bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
{
return lhs->getName() < rhs->getName();
}
bool isTopAndBottomConnected ( Segment* segment, set<const Layer*>& layers )
{
ltrace(88) << "* Potential Null Length: " << segment << endl;
@ -507,7 +497,7 @@ namespace Katabatic {
{ return _configuration; }
void KatabaticEngine::loadGlobalRouting ( unsigned int method, vector<Net*>& nets )
void KatabaticEngine::loadGlobalRouting ( unsigned int method, NetSet& nets )
{
if ( _state < StateGlobalLoaded )
throw Error ("KatabaticEngine::loadGlobalRouting() : global routing not present yet.");
@ -522,10 +512,10 @@ namespace Katabatic {
if ( net->getType() == Net::Type::GROUND ) continue;
if ( net->getType() == Net::Type::CLOCK ) continue;
if ( af->isOBSTACLE(net->getName()) ) continue;
_routingNets.push_back ( *net );
_routingNets.insert ( *net );
}
} else {
vector<Net*>::iterator it = nets.begin();
NetSet::iterator it = nets.begin();
for ( ; it != nets.end() ; it++ ) {
if ( ( (*it)->getType() == Net::Type::POWER )
|| ( (*it)->getType() == Net::Type::GROUND )
@ -533,7 +523,7 @@ namespace Katabatic {
|| ( af->isOBSTACLE((*it)->getName()) ) ) {
cerr << Warning("%s is not a routable net, removed from set.",getString(*it).c_str()) << endl;
} else
_routingNets.push_back ( *it );
_routingNets.insert ( *it );
}
}

View File

@ -181,8 +181,9 @@ namespace Katabatic {
{
cmess1 << " o Assign Layer (simple wirelength)." << endl;
for ( size_t i=0 ; i < _routingNets.size() ; i++ )
_layerAssignByLength ( _routingNets[i], total, global, globalNets );
NetSet::iterator inet = _routingNets.begin();
for ( ; inet != _routingNets.end() ; ++inet )
_layerAssignByLength ( *inet, total, global, globalNets );
}
@ -239,8 +240,9 @@ namespace Katabatic {
{
cmess1 << " o Assign Layer (whole net trunk)." << endl;
for ( size_t i=0 ; i < _routingNets.size() ; i++ )
_layerAssignByTrunk ( _routingNets[i], total, global, globalNets );
NetSet::iterator inet = _routingNets.begin();
for ( ; inet != _routingNets.end() ; ++inet )
_layerAssignByTrunk ( *inet, total, global, globalNets );
}
@ -290,8 +292,9 @@ namespace Katabatic {
_check ( "after layer assignment" );
#endif
#if defined(CHECK_DETERMINISM)
for ( size_t i=0 ; i < _routingNets.size() ; i++ )
_print ( _routingNets[i] );
NetSet::iterator inet = _routingNets.begin();
for ( ; inet != _routingNets.end() ; inet++ )
_print ( *inet );
#endif
// Look for RoutingPad overload.

View File

@ -1847,11 +1847,12 @@ namespace {
ltrace(99) << "_GCell_1G_1L1() [Managed Configuration - Optimized] " << _topology << endl;
ltracein(99);
bool haccess = false;
Hook* globalHook = NULL;
if ( _east ) globalHook = _east;
else if ( _west ) globalHook = _west;
else if ( _north ) globalHook = _north;
else if ( _south ) globalHook = _south;
if ( _east ) { globalHook = _east; haccess = true; }
else if ( _west ) { globalHook = _west; haccess = true; }
else if ( _north ) { globalHook = _north; }
else if ( _south ) { globalHook = _south; }
//Segment* globalSegment = dynamic_cast<Segment*>(globalHook->getComponent());
//DbU::Unit length = (globalSegment) ? globalSegment->getLength() : 0;
@ -1859,7 +1860,7 @@ namespace {
AutoContact* rpContact = _GCell_rp_Access ( _gcell
, _routingPads[0]
, (_topology & GLOBAL_HORIZONTAL_END)
, false //(length > DbU::lambda(50.0*2))
, haccess //(length > DbU::lambda(50.0*2))
);
_GCell_GlobalContacts ( false, rpContact );
@ -2299,14 +2300,16 @@ namespace Katabatic {
startMeasures ();
Session::open ( this );
sort ( _routingNets.begin(), _routingNets.end(), NetCompareByName() );
for ( size_t i=0 ; i < _routingNets.size() ; i++ )
_loadNetGlobalRouting ( _routingNets[i] );
//sort ( _routingNets.begin(), _routingNets.end(), NetCompareByName() );
NetSet::iterator inet = _routingNets.begin();
while ( inet != _routingNets.end() ) {
_loadNetGlobalRouting ( *(inet++) );
}
Session::revalidate ();
for ( size_t i=0 ; i < _routingNets.size() ; i++ )
_toOptimals ( _routingNets[i] );
for ( inet=_routingNets.begin() ; inet != _routingNets.end() ; ++inet )
_toOptimals ( *inet );
Session::revalidate ();
@ -2355,6 +2358,8 @@ namespace Katabatic {
ltracein(99);
Hook* startHook = NULL;
GCell* lowestGCell = NULL;
size_t unconnecteds = 0;
size_t connecteds = 0;
ltrace(99) << "Start RoutingPad Ring" << endl;
forEach ( RoutingPad*, startRp, routingPads ) {
forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) {
@ -2362,23 +2367,38 @@ namespace Katabatic {
Segment* segment = dynamic_cast<Segment*>(ihook->getComponent());
if ( segment ) {
++connecteds;
GCellConfiguration gcellConf ( getGCellGrid(), *ihook, NULL );
if ( gcellConf.getStateG() == 1 ) {
if ( !lowestGCell || (lowestGCell->getIndex() > gcellConf.getGCell()->getIndex()) ) {
if ( (lowestGCell == NULL) or (lowestGCell->getIndex() > gcellConf.getGCell()->getIndex()) ) {
ltrace(99) << "Starting from GCell " << gcellConf.getGCell() << endl;
lowestGCell = gcellConf.getGCell();
startHook = *ihook;
}
break;
}
} else {
++unconnecteds;
}
}
if ( (unconnecteds > 10) and (connecteds == 0) ) {
cerr << Warning("More than 10 unconnected RoutingPads (%u) on %s, missing global routing?"
,unconnecteds, getString(net->getName()).c_str() ) << endl;
_routingNets.erase ( net );
ltraceout(99);
DebugSession::close ();
return;
}
// Comment the next line to enable the lowest GCell search.
//if ( startHook ) break;
}
ltraceout(99);
if ( !startHook ) { singleGCell ( this, net ); ltraceout(99); return; }
if ( startHook == NULL ) { singleGCell ( this, net ); ltraceout(99); return; }
GCellConfiguration startGCellConf ( getGCellGrid(), startHook, NULL );
startGCellConf.construct ( forks );
@ -2398,6 +2418,18 @@ namespace Katabatic {
lookupClear ();
set<AutoSegment*> overconstraineds;
_computeNetConstraints ( net, overconstraineds );
Session::revalidate ();
set<AutoSegment*>::iterator iover = overconstraineds.begin();
for ( ; iover != overconstraineds.end() ; ++iover ) {
(*iover)->makeDogLeg ( (*iover)->getAutoSource()->getGCell(), true );
}
Session::revalidate ();
ltraceout(99);
DebugSession::close ();

View File

@ -83,6 +83,7 @@ namespace {
, DbU::Unit constraintMin
, DbU::Unit constraintMax
, unsigned int direction
, set<AutoSegment*>& faileds
)
{
ltracein(99);
@ -90,15 +91,16 @@ namespace {
while ( !segmentStack.isEmpty() ) {
AutoContact* sourceContact = segmentStack.getAutoContact ();
Segment* sourceSegment = segmentStack.getSegment ();
AutoSegment* sourceAutoSegment = Session::lookup ( sourceSegment );
segmentStack.pop ();
if ( sourceContact->isAlignate(direction) ) {
ltrace(99) << "Apply to (source): " << (void*)sourceContact->base() << ":" << sourceContact << endl;
sourceContact->restrictConstraintBox ( constraintMin, constraintMax, direction );
if ( not sourceContact->restrictConstraintBox(constraintMin,constraintMax,direction,false) )
faileds.insert ( sourceAutoSegment );
}
AutoSegment* sourceAutoSegment = Session::lookup ( sourceSegment );
forEach ( Component*, icomponent, sourceContact->getSlaveComponents() ) {
if ( *icomponent == sourceSegment ) continue;
@ -119,7 +121,7 @@ namespace {
AutoContact* targetContact = Session::lookup
( dynamic_cast<Contact*>(targetAutoSegment->getOppositeAnchor(sourceContact->base())) );
if ( sourceAutoSegment && targetAutoSegment ) {
if ( sourceAutoSegment and targetAutoSegment ) {
unsigned int state = AutoSegment::getPerpandicularState
( sourceContact
, sourceAutoSegment
@ -136,7 +138,8 @@ namespace {
&& (targetAutoSegment->getDirection() == direction)
&& targetContact->isAlignate(direction) ) {
ltrace(99) << "Apply to (target): " << (void*)targetContact->base() << ":" << targetContact << endl;
targetContact->restrictConstraintBox ( constraintMin, constraintMax, direction );
if ( not targetContact->restrictConstraintBox(constraintMin,constraintMax,direction,false) )
faileds.insert ( targetAutoSegment );
}
continue;
}
@ -150,7 +153,7 @@ namespace {
}
void propagateConstraintFromRp ( RoutingPad* rp )
void propagateConstraintFromRp ( RoutingPad* rp, set<AutoSegment*>& faileds )
{
ltrace(99) << "propagateConstraintFromRp() - " << (void*)rp << " " << rp << endl;
@ -249,14 +252,16 @@ namespace {
propagateConstraint ( horizontalSegmentsStack
, constraintBox.getYMin()
, constraintBox.getYMax()
, Constant::Horizontal );
, Constant::Horizontal
, faileds );
// Propagate constraint through vertically bound segments.
ltrace(99) << "Propagate constraint on vertical segments" << endl;
propagateConstraint ( verticalSegmentsStack
, constraintBox.getXMin()
, constraintBox.getXMax()
, Constant::Vertical );
, Constant::Vertical
, faileds );
}
}
@ -275,7 +280,7 @@ namespace Katabatic {
using Hurricane::Cell;
void KatabaticEngine::_computeNetConstraints ( Net* net )
void KatabaticEngine::_computeNetConstraints ( Net* net, set<AutoSegment*>& faileds )
{
DebugSession::open ( net );
@ -298,7 +303,7 @@ namespace Katabatic {
}
for ( size_t i=0 ; i<routingPads.size() ; i++ )
propagateConstraintFromRp ( routingPads[i] );
propagateConstraintFromRp ( routingPads[i], faileds );
set<AutoSegment*> processeds;
forEach ( Segment*, isegment, net->getSegments() ) {

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
@ -243,6 +243,8 @@ namespace Katabatic {
ltrace(110) << "Katabatic::Session::_revalidateTopology()" << endl;
ltracein(110);
set<AutoSegment*> faileds;
if ( not _netInvalidateds.empty() ) {
set<Net*>::iterator inet = _netInvalidateds.begin();
@ -263,9 +265,8 @@ namespace Katabatic {
if ( _invalidateMask & NetCanonize ) {
for ( ; inet != _netInvalidateds.end() ; inet++ ) {
ltrace(110) << "Katabatic::Session::_revalidateTopoplogy(Net*)" << *inet << endl;
_katabatic->_computeNetConstraints ( *inet );
ltrace(110) << "Katabatic::Session::_revalidateTopology(Net*)" << *inet << endl;
_katabatic->_computeNetConstraints ( *inet, faileds );
_katabatic->_computeNetOptimals ( *inet );
_katabatic->_computeNetTerminals ( *inet );
}

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
@ -221,9 +221,10 @@ namespace Katabatic {
inline void setCBYMin ( DbU::Unit yMin );
inline void setCBYMax ( DbU::Unit yMax );
void setConstraintBox ( const Box& box );
void restrictConstraintBox ( DbU::Unit constraintMin
bool restrictConstraintBox ( DbU::Unit constraintMin
, DbU::Unit constraintMax
, unsigned int direction );
, unsigned int direction
, bool warnOnError=true );
void restoreNativeConstraintBox ();
void breakUp ();
void split ();

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//

View File

@ -33,7 +33,7 @@
#include "hurricane/Timer.h"
#include "hurricane/DbU.h"
#include "hurricane/Nets.h"
#include "hurricane/Net.h"
namespace Hurricane {
class Name;
@ -95,11 +95,25 @@ namespace Katabatic {
};
// -------------------------------------------------------------------
// Functors.
struct NetCompareByName {
inline bool operator() ( const Net* lhs, const Net* rhs ) const;
};
inline bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
{ return lhs->getName() < rhs->getName(); }
// -------------------------------------------------------------------
// Class : "KatabaticEngine".
class KatabaticEngine : public ToolEngine {
public:
typedef set<Net*,NetCompareByName> NetSet;
public:
// Constructor.
@ -121,7 +135,7 @@ namespace Katabatic {
inline const Layer* getRoutingLayer ( size_t depth ) const ;
inline Layer* getContactLayer ( size_t depth ) const ;
inline GCellGrid* getGCellGrid () const;
inline const vector<Net*>& getRoutingNets () const;
inline const NetSet& getRoutingNets () const;
inline DbU::Unit getGlobalThreshold () const;
inline float getSaturateRatio () const;
inline DbU::Unit getExtensionCap () const;
@ -142,12 +156,15 @@ namespace Katabatic {
void refresh ( bool openSession=true );
void makePowerRails ();
virtual void createDetailedGrid ();
virtual void loadGlobalRouting ( unsigned int method, vector<Net*>& );
virtual void loadGlobalRouting ( unsigned int method, NetSet& );
void layerAssign ( unsigned int method );
// void computeNetConstraints ();
// void computeNetOptimals ();
virtual void finalizeLayout ();
// Internal Modifiers.
void _computeNetConstraints ( Net*, set<AutoSegment*>& faileds );
void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* );
bool _check ( const char* message=NULL ) const;
void _check ( Net* ) const;
void _gutKatabatic ();
@ -169,12 +186,9 @@ namespace Katabatic {
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( Net* , unsigned long& total, unsigned long& global, set<Net*>& );
void _splitContactsOfNet ( Net* );
void _computeNetConstraints ( Net* );
void _collapseNet ( const Name& , unsigned int depth=1 );
void _collapseNet ( Net* , unsigned int depth=1 );
void _collapseNets ( Nets , unsigned int depth=1 );
void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* );
void _toOptimals ( Net*, bool onlyNew=false );
void _saveNet ( Net* );
void _print () const;
@ -197,7 +211,7 @@ namespace Katabatic {
bool _warnGCellOverload;
Configuration* _configuration;
GCellGrid* _gcellGrid;
vector<Net*> _routingNets;
NetSet _routingNets;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
@ -233,7 +247,7 @@ namespace Katabatic {
inline const Layer* KatabaticEngine::getRoutingLayer ( size_t depth ) const { return _configuration->getRoutingLayer(depth); }
inline Layer* KatabaticEngine::getContactLayer ( size_t depth ) const { return _configuration->getContactLayer(depth); }
inline GCellGrid* KatabaticEngine::getGCellGrid () const { return _gcellGrid; }
inline const vector<Net*>& KatabaticEngine::getRoutingNets () const { return _routingNets; }
inline const KatabaticEngine::NetSet& KatabaticEngine::getRoutingNets () const { return _routingNets; }
inline DbU::Unit KatabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline float KatabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline DbU::Unit KatabaticEngine::getExtensionCap () const { return _configuration->getExtensionCap(); }
@ -242,8 +256,6 @@ namespace Katabatic {
inline void KatabaticEngine::setState ( EngineState state ) { _state = state; }
// -------------------------------------------------------------------
// Global Variables.

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
@ -32,6 +32,7 @@
#include <vector>
#include <set>
#include <map>
#include <boost/function.hpp>
#include "hurricane/Commons.h"
#include "hurricane/DbU.h"
@ -81,7 +82,6 @@ namespace Katabatic {
class Session {
public:
enum InvalidateType { NetSplitContacts = (1<<0)
, NetCanonize = (1<<1)