Exemple #1
0
void CodeGen::genFloatLeaf(GenTree *tree, RegSet::RegisterPreference *pref)
{
    regNumber reg = REG_NA;

    switch (tree->OperGet())
    {
    case GT_LCL_VAR:
        // Does the variable live in a register?
        //
        if  (!genMarkLclVar(tree))
            goto MEM_LEAF;
        __fallthrough;

    case GT_REG_VAR:
        noway_assert(tree->gtFlags & GTF_REG_VAL);
        reg = tree->gtRegVar.gtRegNum; 
        break;

    case GT_LCL_FLD:
        // We only use GT_LCL_FLD for lvAddrTaken vars, so we don't have
        // to worry about it being enregistered.
        noway_assert(compiler->lvaTable[tree->gtLclFld.gtLclNum].lvRegister == 0);
        __fallthrough;

    case GT_CLS_VAR:

MEM_LEAF:
        reg = regSet.PickRegFloat(tree->TypeGet(), pref);
        genLoadFloat(tree, reg);    
        break;

    default:
        DISPTREE(tree);
        assert(!"unexpected leaf");
    }

    genCodeForTreeFloat_DONE   (tree, reg);
    return;
}
Exemple #2
0
//------------------------------------------------------------------------
// DecomposeInd: Decompose GT_IND.
//
// Arguments:
//    tree - the tree to decompose
//
// Return Value:
//    None.
//
void DecomposeLongs::DecomposeInd(GenTree** ppTree, Compiler::fgWalkData* data)
{
    GenTreePtr indLow = *ppTree;
    GenTreeStmt* addrStmt = CreateTemporary(&indLow->gtOp.gtOp1);
    JITDUMP("[DecomposeInd]: Saving addr tree to a temp var:\n");
    DISPTREE(addrStmt);

    // Change the type of lower ind.
    indLow->gtType = TYP_INT;

    // Create tree of ind(addr+4)
    GenTreePtr addrBase = indLow->gtGetOp1();
    GenTreePtr addrBaseHigh = new(m_compiler, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR,
        addrBase->TypeGet(), addrBase->AsLclVarCommon()->GetLclNum(), BAD_IL_OFFSET);
    GenTreePtr addrHigh = new(m_compiler, GT_LEA) GenTreeAddrMode(TYP_REF, addrBaseHigh, nullptr, 0, genTypeSize(TYP_INT));
    GenTreePtr indHigh = new (m_compiler, GT_IND) GenTreeIndir(GT_IND, TYP_INT, addrHigh, nullptr);
    
    // Connect linear links
    SimpleLinkNodeAfter(addrBaseHigh, addrHigh);
    SimpleLinkNodeAfter(addrHigh, indHigh);

    FinalizeDecomposition(ppTree, data, indLow, indHigh);
}
Exemple #3
0
//------------------------------------------------------------------------
// DecomposeStoreInd: Decompose GT_STOREIND.
//
// Arguments:
//    tree - the tree to decompose
//
// Return Value:
//    None.
//
void DecomposeLongs::DecomposeStoreInd(GenTree** ppTree, Compiler::fgWalkData* data)
{
    assert(ppTree != nullptr);
    assert(*ppTree != nullptr);
    assert(data != nullptr);
    assert((*ppTree)->OperGet() == GT_STOREIND);
    assert(m_compiler->compCurStmt != nullptr);

    GenTree* tree = *ppTree;

    assert(tree->gtOp.gtOp2->OperGet() == GT_LONG);

    GenTreeStmt* curStmt = m_compiler->compCurStmt->AsStmt();
    bool isEmbeddedStmt = !curStmt->gtStmtIsTopLevel();

    // Example input trees (a nested embedded statement case)
    //
    //   <linkBegin Node>
    //   *  stmtExpr  void  (top level) (IL   ???...  ???)
    //   |  /--*  argPlace  ref    $280
    //   |  +--*  argPlace  int    $4a
    //   |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //   |  |  {  |     /--*  lclVar    ref    V11 tmp9         u:3 $21c
    //   |  |  {  |     +--*  const     int    4 $44
    //   |  |  {  |  /--*  +         byref  $2c8
    //   |  |  {  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //   |  |  {  |  |     {  |  /--*  lclFld    long   V01 arg1         u:2[+8] Fseq[i] $380
    //   |  |  {  |  |     {  \--*  st.lclVar long  (P) V21 cse8
    //   |  |  {  |  |     {  \--*    int    V21.hi (offs=0x00) -> V22 rat0    
    //   |  |  {  |  |     {  \--*    int    V21.hi (offs=0x04) -> V23 rat1    
    //   |  |  {  |  |  /--*  lclVar    int    V22 rat0          $380
    //   |  |  {  |  |  +--*  lclVar    int    V23 rat1
    //   |  |  {  |  +--*  gt_long   long
    //   |  |  {  \--*  storeIndir long
    //   |  +--*  lclVar    ref    V11 tmp9         u:3 (last use) $21c
    //   |  +--*  lclVar    ref    V02 tmp0         u:3 $280
    //   |  +--*  const     int    8 $4a
    //   \--*  call help void   HELPER.CORINFO_HELP_ARRADDR_ST $205
    //  <linkEndNode>
    //
    // (editor brace matching compensation: }}}}}}}}}}}}}}}}}})

    GenTree* linkBegin = m_compiler->fgGetFirstNode(tree)->gtPrev;
    GenTree* linkEnd = tree->gtNext;
    GenTree* gtLong = tree->gtOp.gtOp2;

    // Save address to a temp. It is used in storeIndLow and storeIndHigh trees.
    GenTreeStmt* addrStmt = CreateTemporary(&tree->gtOp.gtOp1);
    JITDUMP("[DecomposeStoreInd]: Saving address tree to a temp var:\n");
    DISPTREE(addrStmt);

    if (!gtLong->gtOp.gtOp1->OperIsLeaf())
    {
        GenTreeStmt* dataLowStmt = CreateTemporary(&gtLong->gtOp.gtOp1);
        JITDUMP("[DecomposeStoreInd]: Saving low data tree to a temp var:\n");
        DISPTREE(dataLowStmt);
    }

    if (!gtLong->gtOp.gtOp2->OperIsLeaf())
    {
        GenTreeStmt* dataHighStmt = CreateTemporary(&gtLong->gtOp.gtOp2);
        JITDUMP("[DecomposeStoreInd]: Saving high data tree to a temp var:\n");
        DISPTREE(dataHighStmt);
    }

    // Example trees after embedded statements for address and data are added.
    // This example saves all address and data trees into temp variables 
    // to show how those embedded statements are created.
    //
    //  *  stmtExpr  void  (top level) (IL   ???...  ???)
    //  |  /--*  argPlace  ref    $280
    //  |  +--*  argPlace  int    $4a
    //  |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |     /--*  lclVar    ref    V11 tmp9         u:3 $21c
    //  |  |  {  |     +--*  const     int    4 $44
    //  |  |  {  |  /--*  +         byref  $2c8
    //  |  |  {  \--*  st.lclVar byref  V24 rat2
    //  |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |  /--*  lclVar    byref  V24 rat2
    //  |  |  {  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |  |     {  |  /--*  lclFld    long   V01 arg1         u:2[+8] Fseq[i] $380380
    //  |  |  {  |  |     {  \--*  st.lclVar long  (P) V21 cse8
    //  |  |  {  |  |     {  \--*    int    V21.hi (offs=0x00) -> V22 rat0
    //  |  |  {  |  |     {  \--*    int    V21.hi (offs=0x04) -> V23 rat1
    //  |  |  {  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |  |     {  |  /--*  lclVar    int    V22 rat0          $380
    //  |  |  {  |  |     {  \--*  st.lclVar int    V25 rat3
    //  |  |  {  |  |  /--*  lclVar    int    V25 rat3
    //  |  |  {  |  |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |  |  |  {  |  /--*  lclVar    int    V23 rat1
    //  |  |  {  |  |  |  {  \--*  st.lclVar int    V26 rat4
    //  |  |  {  |  |  +--*  lclVar    int    V26 rat4
    //  |  |  {  |  +--*  gt_long   long
    //  |  |  {  \--*  storeIndir long
    //  |  +--*  lclVar    ref    V11 tmp9         u:3 (last use) $21c
    //  |  +--*  lclVar    ref    V02 tmp0         u:3 $280
    //  |  +--*  const     int    8 $4a
    //  \--*  call help void   HELPER.CORINFO_HELP_ARRADDR_ST $205
    //
    // (editor brace matching compensation: }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})

    GenTree* addrBase = tree->gtOp.gtOp1;
    GenTree* dataHigh = gtLong->gtOp.gtOp2;
    GenTree* dataLow = gtLong->gtOp.gtOp1;
    GenTree* storeIndLow = tree;

    // Rewrite storeIndLow tree to save only lower 32-bit data.
    // 
    //  |  |  {  |  /--*  lclVar    byref  V24 rat2   (address)
    //  ...
    //  |  |  {  |  +--*  lclVar    int    V25 rat3   (lower 32-bit data)
    //  |  |  {  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |  {  |  {  |  /--*  lclVar    int    V23 rat1
    //  |  |  {  |  {  \--*  st.lclVar int    V26 rat4
    //  |  |  {  \--*  storeIndir int
    //
    // (editor brace matching compensation: }}}}}}}}})

    m_compiler->fgSnipNode(curStmt, gtLong);
    m_compiler->fgSnipNode(curStmt, dataHigh);
    storeIndLow->gtOp.gtOp2 = dataLow;
    storeIndLow->gtType = TYP_INT;

    // Construct storeIndHigh tree
    //
    // | | {  *stmtExpr  void  (embedded)(IL ? ? ? ... ? ? ? )
    // | | { | / --*  lclVar    int    V26 rat4
    // | | { | | / --*  lclVar    byref  V24 rat2
    // | | { | +--*  lea(b + 4)  ref
    // | | {  \--*  storeIndir int
    //
    // (editor brace matching compensation: }}}}})

    GenTree* addrBaseHigh = new(m_compiler, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, 
        addrBase->TypeGet(), addrBase->AsLclVarCommon()->GetLclNum(), BAD_IL_OFFSET);
    GenTree* addrHigh = new(m_compiler, GT_LEA) GenTreeAddrMode(TYP_REF, addrBaseHigh, nullptr, 0, genTypeSize(TYP_INT));
    GenTree* storeIndHigh = new(m_compiler, GT_STOREIND) GenTreeStoreInd(TYP_INT, addrHigh, dataHigh);
    storeIndHigh->gtFlags = (storeIndLow->gtFlags & (GTF_ALL_EFFECT | GTF_LIVENESS_MASK));
    storeIndHigh->gtFlags |= GTF_REVERSE_OPS;
    storeIndHigh->CopyCosts(storeIndLow);

    // Internal links of storeIndHigh tree
    dataHigh->gtPrev = nullptr;
    dataHigh->gtNext = nullptr;
    SimpleLinkNodeAfter(dataHigh, addrBaseHigh);
    SimpleLinkNodeAfter(addrBaseHigh, addrHigh);
    SimpleLinkNodeAfter(addrHigh, storeIndHigh);
    
    // External links of storeIndHigh tree
    //dataHigh->gtPrev = nullptr;
    if (isEmbeddedStmt)
    {
        // If storeIndTree is an embedded statement, connect storeIndLow
        // and dataHigh
        storeIndLow->gtNext = dataHigh;
        dataHigh->gtPrev = storeIndLow;
    }
    storeIndHigh->gtNext = linkEnd;
    if (linkEnd != nullptr)
    {
        linkEnd->gtPrev = storeIndHigh;
    }

    InsertNodeAsStmt(storeIndHigh);

    // Example final output 
    //
    //  *  stmtExpr  void  (top level) (IL   ???...  ???)
    //  |  /--*  argPlace  ref    $280
    //  |  +--*  argPlace  int    $4a
    //  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |     /--*  lclVar    ref    V11 tmp9         u:3 $21c
    //  |  |     {  |     +--*  const     int    4 $44
    //  |  |     {  |  /--*  +         byref  $2c8
    //  |  |     {  \--*  st.lclVar byref  V24 rat2
    //  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |  /--*  lclVar    byref  V24 rat2
    //  |  |     {  |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |  |  {  |     /--*  lclFld    int    V01 arg1         u:2[+8] Fseq[i] $380
    //  |  |     {  |  |  {  |     +--*  lclFld    int    V01 arg1         [+12]
    //  |  |     {  |  |  {  |  /--*  gt_long   long
    //  |  |     {  |  |  {  \--*  st.lclVar long  (P) V21 cse8
    //  |  |     {  |  |  {  \--*    int    V21.hi (offs=0x00) -> V22 rat0    
    //  |  |     {  |  |  {  \--*    int    V21.hi (offs=0x04) -> V23 rat1    
    //  |  |     {  |  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |  |  {  |  /--*  lclVar    int    V22 rat0          $380
    //  |  |     {  |  |  {  \--*  st.lclVar int    V25 rat3
    //  |  |     {  |  +--*  lclVar    int    V25 rat3
    //  |  |     {  |  {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |  {  |  /--*  lclVar    int    V23 rat1
    //  |  |     {  |  {  \--*  st.lclVar int    V26 rat4
    //  |  |     {  \--*  storeIndir int
    //  |  |     {  *  stmtExpr  void  (embedded) (IL   ???...  ???)
    //  |  |     {  |  /--*  lclVar    int    V26 rat4
    //  |  |     {  |  |  /--*  lclVar    byref  V24 rat2
    //  |  |     {  |  +--*  lea(b+4)  ref
    //  |  |     {  \--*  storeIndir int
    //  |  |  /--*  lclVar    ref    V11 tmp9         u:3 (last use) $21c
    //  |  +--*  putarg_stk [+0x00] ref
    //  |  |  /--*  lclVar    ref    V02 tmp0         u:3 $280
    //  |  +--*  putarg_reg ref
    //  |  |  /--*  const     int    8 $4a
    //  |  +--*  putarg_reg int
    //  \--*  call help void   HELPER.CORINFO_HELP_ARRADDR_ST $205
    //
    // (editor brace matching compensation: }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})
}