~ubuntu-branches/ubuntu/wily/verilator/wily-proposed

« back to all changes in this revision

Viewing changes to src/V3Premit.cpp

  • Committer: Package Import Robot
  • Author(s): أحمد المحمودي (Ahmed El-Mahmoudy)
  • Date: 2015-04-26 16:20:52 UTC
  • mfrom: (4.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20150426162052-69yjwh512m0adl2k
Tags: 3.872-2
* Upload to unstable.
* debian/patches/*: Added DEP-3 patch headers.
* Remove debian/gbp.conf, not needed in master branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
//
7
7
//*************************************************************************
8
8
//
9
 
// Copyright 2003-2014 by Wilson Snyder.  This program is free software; you can
 
9
// Copyright 2003-2015 by Wilson Snyder.  This program is free software; you can
10
10
// redistribute it and/or modify it under the terms of either the GNU
11
11
// Lesser General Public License Version 3 or the Perl Artistic License
12
12
// Version 2.0.
124
124
 
125
125
    bool assignNoTemp(AstNodeAssign* nodep) {
126
126
        return (nodep->lhsp()->castVarRef()
127
 
                && !nodep->lhsp()->castVarRef()->varp()->isSc()
 
127
                && !AstVar::scVarRecurse(nodep->lhsp())
128
128
                && nodep->rhsp()->castConst());
129
129
    }
130
130
    void checkNode(AstNode* nodep) {
138
138
        //UINFO(9, "     Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user1()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
139
139
        if (m_stmtp
140
140
            && !nodep->user1()) {       // Not already done
141
 
            if (nodep->isWide()) {              // Else might be cell interconnect or something
 
141
            if (nodep->isWide()) {
142
142
                if (m_assignLhs) {
143
143
                } else if (nodep->firstAbovep()
144
144
                           && nodep->firstAbovep()->castNodeAssign()
148
148
                           && nodep->firstAbovep()->castArraySel()) {  // ArraySel's are pointer refs, ignore
149
149
                } else {
150
150
                    UINFO(4,"Cre Temp: "<<nodep<<endl);
151
 
                    createDeepTemp(nodep);
 
151
                    createDeepTemp(nodep, false);
152
152
                }
153
153
            }
154
154
        }
157
157
    AstVar* getBlockTemp(AstNode* nodep) {
158
158
        string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
159
159
        AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
160
 
                                   VFlagLogicPacked(), nodep->widthMin());
 
160
                                   nodep->dtypep());
161
161
        m_funcp->addInitsp(varp);
162
162
        return varp;
163
163
    }
180
180
        }
181
181
    }
182
182
 
183
 
    void createDeepTemp(AstNode* nodep) {
 
183
    void createDeepTemp(AstNode* nodep, bool noSubst) {
184
184
        if (debug()>8) nodep->dumpTree(cout,"deepin:");
185
185
 
186
186
        AstNRelinker linker;
187
187
        nodep->unlinkFrBack(&linker);
188
188
 
189
189
        AstVar* varp = getBlockTemp(nodep);
 
190
        if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const
190
191
        // Replace node tree with reference to var
191
192
        AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
192
193
        linker.relink(newp);
236
237
            if (noopt && !nodep->user1()) {
237
238
                // Need to do this even if not wide, as e.g. a select may be on a wide operator
238
239
                UINFO(4,"Deep temp for LHS/RHS\n");
239
 
                createDeepTemp(nodep->rhsp());
 
240
                createDeepTemp(nodep->rhsp(), false);
240
241
            }
241
242
        }
242
243
        nodep->rhsp()->iterateAndNext(*this);
337
338
            && !nodep->condp()->castVarRef()) {
338
339
            // We're going to need the expression several times in the expanded code,
339
340
            // so might as well make it a common expression
340
 
            createDeepTemp(nodep->condp());
 
341
            createDeepTemp(nodep->condp(), false);
341
342
        }
342
343
        checkNode(nodep);
343
344
    }
352
353
            while (searchp && searchp->castComment()) searchp = searchp->nextp();
353
354
            if (searchp
354
355
                && searchp->castDisplay()
355
 
                && nodep->filep()->sameTree(searchp->castDisplay()->filep())) {
 
356
                && nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) {
356
357
                // There's another display next; we can just wait to flush
357
358
            } else {
358
359
                UINFO(4,"Autoflush "<<nodep<<endl);
361
362
            }
362
363
        }
363
364
    }
 
365
    virtual void visit(AstSFormatF* nodep, AstNUser*) {
 
366
        nodep->iterateChildren(*this);
 
367
        // Any strings sent to a display must be var of string data type,
 
368
        // to avoid passing a pointer to a temporary.
 
369
        for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
 
370
            if (expp->dtypep()->basicp()->isString()
 
371
                && !expp->castVarRef()) {
 
372
                createDeepTemp(expp, true);
 
373
            }
 
374
        }
 
375
    }
364
376
 
365
377
    //--------------------
366
378
    // Default: Just iterate
391
403
void V3Premit::premitAll(AstNetlist* nodep) {
392
404
    UINFO(2,__FUNCTION__<<": "<<endl);
393
405
    PremitVisitor visitor (nodep);
 
406
    V3Global::dumpCheckGlobalTree("premit.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
394
407
}