void ConstantArrayPropagationPass::CollectInitializations()
{
  if (!initializations.empty())
  {
    initializations.clear() ;
  }

  DefinitionBlock* procDefBlock = procDef->get_definition_block() ;
  assert(procDefBlock != NULL) ;
  Iter<VariableDefinition*> varDefIter = 
    procDefBlock->get_variable_definition_iterator() ;
  while (varDefIter.is_valid())
  {    
    VariableDefinition* varDef = varDefIter.current() ;
    assert(varDef != NULL) ;

    VariableSymbol* varSym = varDef->get_variable_symbol() ;
    ValueBlock* valBlock = varDef->get_initialization() ;
    assert(varSym != NULL) ;
    assert(valBlock != NULL) ;

    if (ValidSymbol(varSym)) 
    {
      initializations[varSym] = valBlock ;
      varSym->append_annote(create_brick_annote(theEnv, "ConstPropArray")) ;
    }

    varDefIter.next() ;
  }
}
Esempio n. 2
0
void SingleInheritanceVtbls::attach_vtbl( SingleInheritanceClassType* ctype,
					  VariableSymbol* vsym ) {
  VariableDefinition* vdef = get_vtbl( ctype );
  vdef->set_variable_symbol( vsym );
  vsym->set_definition( vdef );

  // Insert reference to vsym in ClassType
  ctype->set_vtbl_symbol( vsym );

  // Insert vdef in ClassType
  ctype->get_definition_block()->append_variable_definition( vdef );

  // Set type of vsym
  DataType* vtbl_type =
    vdef->get_initialization()->get_type();
  QualifiedType* q_vtbl_type =  _tb->get_qualified_type( vtbl_type );
  vsym->set_type( q_vtbl_type );
}
Esempio n. 3
0
/*
 * print_var_def() -- Generates assembly language data statements.
 * Data objects are put into the sdata section, data section, comm
 * section, or the lcomm section.  If the data object is global, I
 * also specify a .globl pseudo-op.
 */
void
PrinterX86::print_var_def(VarSym *vsym)
{
    int vsym_size = get_bit_size(get_type(vsym)) >> 3;	// in bytes
    VariableDefinition *vdef = vsym->get_definition();

    if (vdef == NULL
	|| (vdef->get_initialization() == NULL)	// FIXME: shouldn't be possible
	||  is_a<UndefinedValueBlock>(vdef->get_initialization())) {

	// Uninitialized data item.  If global symbol, append to
	// .comm, else static symbol to .lcomm.
	if (is_global(vsym) && !is_private(vsym))
	    fprintf(out, "\t%s\t", x86_opcode_names[COMM]);
	else
	    fprintf(out, "\t%s\t", x86_opcode_names[LCOMM]);
	print_sym(vsym);
	fprintf(out, ", %d\n", vsym_size);

    } else {		// initialized data item 

	// Specify data section to place data in. On x86, always use
	// .data section.
	fprintf(out, "\t%s\n", x86_opcode_names[DATA]);

	// If global symbol, add .globl pseudo-op.  Note that a variable
	// is considered global in SUIF if it is part of the global or
	// file symbol table.  For X86 assembly, a datum is global only
	// if it is part of the global symbol table (i.e. is_private()
	// checks for def in file symbol table).
	if (is_global(vsym) && !is_private(vsym)) {
	    fprintf(out, "\t%s\t", x86_opcode_names[GLOBL]);
	    print_sym(vsym);
	    fprintf(out, "\n");
	}

	// Determine alignment and align
	int bit_alignment = get_bit_alignment(vdef);
	// If vdef's alignment is zero (shouldn't be!), use that in vsym's type
	if (bit_alignment == 0)
	    bit_alignment = get_bit_alignment(get_type(vsym));
	int alignment_value;
	switch (bit_alignment) {
	  case 8:			// byte aligned
	    alignment_value = 0;
	    break;
	  case 16:			// halfword aligned
	    alignment_value = 1;
	    break;
	  case 32:			// word aligned
	    alignment_value = 2;
	    break;
	  case 64:			// double word aligned
	    alignment_value = 3;
	    break;
	  case 128:			// quad word aligned
	    alignment_value = 4;
	    break;
	  default:
	    claim(false, "bad alignment for %s", get_name(vsym).chars());
	}
	fprintf(out, "\t%s\t%d\n", x86_opcode_names[ALIGN], alignment_value);

	// Disable automatic alignment
	fprintf(out, "\t%s\t%d\t# %s\n", x86_opcode_names[ALIGN], 0,
		      "disable automatic alignment");

	// Write out the label
	print_sym(vsym);
	fprintf(out, ":");		// return added in process_value_block

	// initialize memory with values
	cur_opcode = opcode_null;
	cur_opnd_cnt = 0;
	process_value_block(vdef->get_initialization());
	fprintf(out, "\n");
   }
}
Esempio n. 4
0
    bool Expression::fold(bool mustFold, bool forbidUndefined, std::vector<Definition*>& expansionStack)
    {
        // expansionStack contains a stack of all named constants that are being expanded.
        // This is the max size that this stack is allowed to grow.
        const unsigned int EXPANSION_STACK_MAX = 16;
        
        if(folded)
        {
            return true;
        }
        
        switch(expressionType)
        {
            case NUMBER:
            {
                folded = true;
                foldedValue = number->getValue();
                break;
            }
            case ATTRIBUTE:
            {
                Definition* def = attribute->findDefinition(forbidUndefined);

                // Get the position of the attribute's first element, used for errors.
                SourcePosition* pos = attribute->getPieces()->getList().front()->getSourcePosition();

                if(def)
                {
                    switch(def->getDefinitionType())
                    {
                        case Definition::CONSTANT:
                        {
                            ConstantDefinition* constant = (ConstantDefinition*) def;
                            Expression* expression = constant->getConstantDeclaration()->getExpression();
                            
                            expansionStack.push_back(constant);
                            if(expansionStack.size() > EXPANSION_STACK_MAX)
                            {
                                std::ostringstream os;
                                os << "too many constant expansions required (exceeded max depth " <<
                                    EXPANSION_STACK_MAX << "). are there mutually-dependent constants?";
                                for(size_t i = 0; i < expansionStack.size(); i++)
                                {
                                    Definition* entry = expansionStack[i];
                                    os << std::endl << "    `" << entry->getName() << "` at " <<
                                        entry->getDeclarationPoint();
                                }
                                error(os.str(), pos, true);
                            }
                            else
                            {
                                folded = expression->fold(mustFold, forbidUndefined, expansionStack);
                            }
                            expansionStack.pop_back();
                            
                            foldedValue = expression->getFoldedValue();
                            break;
                        }
                        case Definition::LABEL:
                        {
                            LabelDefinition* label = (LabelDefinition*) def;
                            folded = label->isLocationKnown();
                            foldedValue = label->getLocation();
                            break;
                        }
                        case Definition::VARIABLE:
                        {
                            VariableDefinition* var = (VariableDefinition*) def;
                            folded = true;
                            foldedValue = var->getOffset();
                            break;
                        }
                        case Definition::PACKAGE:
                        {
                            std::ostringstream os;
                            os << "package `" << attribute->getName() << "` may not be directly used in a numeric expression because it's a scope, lacking any address or numeric value.";
                            error(os.str(), pos);
                            folded = false;
                            forbidUndefined = true; // this line is to prevent more the general 'indeterminate value' message below.
                            break;
                        }
                    }
                }
                
                // If there is no known value when one is expected, then error.
                // Another error will trigger instead if undefined attributes are
                // forbidden on the current compiler pass and the symbol wasn't found.
                if((def || !forbidUndefined) && !folded && mustFold)
                {
                    std::ostringstream os;
                    os << "attribute `" << attribute->getName() << "` has an indeterminate value.";
                    error(os.str(), pos);
                }
                break;
            }
            case OPERATION:
            {
                operation->getLeft()->fold(mustFold, forbidUndefined, expansionStack);
                operation->getRight()->fold(mustFold, forbidUndefined, expansionStack);
                
                if(!operation->getLeft()->isFolded() || !operation->getRight()->isFolded())
                {
                    return false;
                }
                
                folded = true;
                
                unsigned int ls = operation->getLeft()->getFoldedValue();
                unsigned int rs = operation->getRight()->getFoldedValue();
                switch(operation->getOperationType())
                {
                    case Operation::MUL:
                    {
                        if(ls > MAX_VALUE / rs)
                        {
                            error("multiplication yields result which will overflow outside of 0..65535.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls * rs;
                        }
                        break;
                    }
                    case Operation::DIV:
                    {
                        if(rs == 0)
                        {
                            error("division by zero is undefined.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls / rs;
                        }
                        break;
                    }
                    case Operation::MOD:
                    {
                        if(rs == 0)
                        {
                            error("modulo by zero is undefined.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls / rs;
                        }
                        break;
                    }
                    case Operation::ADD:
                    {
                        if(ls + MAX_VALUE < rs)
                        {
                            error("addition yields result which will overflow outside of 0..65535.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls + rs;
                        }
                        break;
                    }
                    case Operation::SUB:
                    {
                        if(ls < rs)
                        {
                            error("subtraction yields result which will overflow outside of 0..65535.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls - rs;
                        }
                        break;
                    }
                    case Operation::SHL:
                    {
                        // If shifting more than N bits, or ls << rs > 2^N-1, then error.
                        if(rs > 16 || rs > 0 && (ls & ~(1 << (16 - rs))) != 0)
                        {
                            error("logical shift left yields result which will overflow outside of 0..65535.", operation->getRight()->getSourcePosition());
                            folded = false;
                        }
                        else
                        {
                            foldedValue = ls << rs;
                        }
                        break;
                    }
                    case Operation::SHR:
                    {
                        foldedValue = ls >> rs;
                        break;
                    }
                    case Operation::BITWISE_AND:
                    {
                        foldedValue = ls & rs;
                        break;
                    }
                    case Operation::BITWISE_XOR:
                    {
                        foldedValue = ls ^ rs;
                        break;
                    }
                    case Operation::BITWISE_OR:
                    {
                        foldedValue = ls | rs;
                        break;
                    }
                }
                break;
            }
        }
        return folded;
    }