Studying note of GCC-3.4.6 source (165)

5.13.5.      Code analysis and optimization

5.13.5.1.              Preliminaries- alias set analysis
5.13.5.1.1.        Concept of alias set

In wikipedia , there is a good explaination of alias set given below.

Alias analysis is a technique in compiler theory, used to determine if a storage location may be accessed in more than one way. Two pointers are said to be aliased if they point to the same location.

Alias analysis techniques are usually classified by flow-sensitivity and context-sensitivity. They may determine may-alias or must-alias information. The term alias analysis is often used interchangeably with term points-to analysis, a specific case.

What Does Alias Analysis Do?

In general, alias analysis determines whether or not separate memory references point to the same area of memory. This allows the compiler to determine what variables in the program will be affected by a statement. For example, consider the following section of code that accesses members of structures:

...; p.foo = 1; q.foo = 2; i = p.foo + 3; ...

There are three pos sible alias cases here:

The variables p and q cannot alias.

The variables p and q must alias.

It cannot be conclusively determined at compile time if p and q alias or not.

If p and q cannot alias, then i = p.foo + 3; can be changed to i = 4. If p and q must alias, then i = p.foo + 3; can be changed to i = 5. In both cases, we are able to perform optimizations from the alias knowledge. On the other hand, if it is not known if p and q alias or not, then no optimizations can be performed and the whole of the code must be executed to get the result. Two memory references are said to have a may-alias relation if their aliasing is unknown.

Performing Alias Analysis

In alias analysis, we divide the program's memory into alias classes . Alias classes are disjoint sets of locations that cannot alias to one another. For the discussion here, it is assumed that the optimizations done here occur on a low-level intermediate representation of the program. This is to say that the program has been compiled into binary operations, jumps, moves between registers, moves from registers to memory, moves from memory to registers, branches, and function calls/returns.

Type Based Alias Analysis

If the language being compiled is type safe, the compiler's type checker is correct, and the language lacks the ability to create pointers referencing local variables, (such as ML, Haskell, or Java) then some useful optimizations can be made. There are many cases where we know that two memory locations must be in different alias classes:

1.       Two variables of different types cannot be in the same alias class since it is a property of strongly typed, memory reference-free (i.e. references to memory locations cannot be changed directly) languages that two variables of different types cannot share the same memory location simultaneously.

2.       Allocations local to the current stack frame cannot be in the same alias class as any previous allocation from another stack frame. This is the case because new memory allocations must be disjoint from all other memory allocations.

3.       Each record field of each record type has its own alias class, in general, because the typing discipline usually only allows for records of the same type to alias. Since all records of a type will be stored in an identical format in memory, a field can only alias to itself.

4.       Similarly, each array of a given type has its own alias class.

When performing alias analysis for code, every load and store to memory needs to be labeled with its class. We then have the useful property, given memory locations Ai and Bj with i, j alias classes, that if i = j then Ai may-alias Bj , and if i /neq j   then the memory locations will not alias.

Flow Based Alias Analysis

Analysis based on flow, unlike type based analysis, can be applied to programs in a language with references or type-casting. Flow based analysis can be used in lieu of or to supplement type based analysis. In flow based analysis, new alias classes are created for each memory allocation, and for every global and local variable whose address has been used. References may point to more than one value over time and thus may be in more than one alias class. This means that each memory location has a set of alias classes instead of a single alias class.

No doubt, in GNU C++, both flow based alias analysis and type based analysis are used. As we have seen, for items consuming memory (majorly declarations and constants), they has MEM node associated.

In the compiler, the alias sets assigned to MEMs assist the back-end in determining which MEMs can alias which other MEMs. In general, two MEMs having different alias sets cannot alias each other, with one important exception.

Consider something like: struct S { int i; double d; };

A store to a `S' can alias something (in fact in C++, must be pointer of refernce) of either type `int' or type `double'. (However, a store to an `int' cannot alias a `double' and vice versa.) We indicate this via a tree structure that looks like:

           struct S

            /   /

   /     /

        |/_     _/|

        int    double

  (The arrows are directed and point downwards.) In this situation we say the alias set for `struct S' is the `superset' and that those for `int' and `double' are `subsets'.

To see whether two alias sets can point to the same memory, we must see if either alias set is a subset of the other. We need not trace past immediate descendants, however, since we propagate all grandchildren up one level.

Alias set zero is implicitly a superset of all other alias sets. However, this is no actual entry for alias set zero. It is an error to attempt to explicitly construct a subset of zero.

5.13.5.1.2.        The data structure

In another words, alias set is used to describe the hierarchy and relationship of the memory block that has been accessed in the program. For this purpose, the compiler defines a structure alias_set_entry for alias_set.

 

77    struct alias_set_entry GTY(())                                                                     in alias.c

78    {

79      /* The alias set number, as stored in MEM_ALIAS_SET.  */

80      HOST_WIDE_INT alias_set;

81   

82      /* The children of the alias set. These are not just the immediate

83        children, but, in fact, all descendants. So, if we have:

84   

85           struct T { struct S s; float f; }

86   

87        continuing our example above, the children here will be all of

88        `int', `double', `float', and `struct S'.  */

89      splay_tree GTY((param1_is (int), param2_is (int))) children;

90   

91      /* Nonzero if would have a child of zero: this effectively makes this

92        alias set the same as alias set zero.  */

93      int has_zero_child;

94    };

95    typedef struct alias_set_entry *alias_set_entry;

 

In which, field alias_set at line 80 if zero, means the associated MEM is not in any alias set, and may alias anything (in fact, if alias analysis is in used, alias_set should not be 0, see below). This alias_set also acts as the unique id for alias sets. At line 89, field children is a pointer of splay tree. The splay tree is kind of binary tree and uses alias_set as the order key. And in the node of this splay tree, its value field is unused. So see every alias_set_entry corresponding to each alias set would hold a splay tree if it aliases to other alias sets. And the poistion of the nodes in the tree is good enough to describe the alias relationship.

New alias_set_entry allocated for alias set is done by new_alias_set as below. Flag flag_strict_aliasing is set if optimization option is higher than –O2, for which we should do language-dependent alias analysis.

 

614  HOST_WIDE_INT

615  new_alias_set (void)                                                                                   in alias.c

616  {

617    if (flag_strict_aliasing )

618    {

619      if (!alias_sets )

620        VARRAY_GENERIC_PTR_INIT (alias_sets , 10, "alias sets");

621      else

622        VARRAY_GROW (alias_sets , last_alias_set + 2);

623      return ++last_alias_set ;

624    }

625    else

626      return 0;

627  }

 

Global variable last_alias_set records the number of alias_set_entry allocated so far, and it would be set in alias_set in the alias_set_entry allocated this time.

And function record_alias_subset helps to construct the alias tree by inserting subset into the tree rooted by superset to make superset being a superset of subset .

 

642  void

643  record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset) in alias.c

644  {

645    alias_set_entry superset_entry;

646    alias_set_entry subset_entry;

647 

648    /* It is possible in complex type situations for both sets to be the same,

649      i n which case we can ignore this operation.  */

650    if (superset == subset)

651      return ;

652 

653    if (superset == 0)

654      abort ();

655 

656    superset_entry = get_alias_set_entry (superset);

657    if (superset_entry == 0)

658    {

659      /* Create an entry for the SUPERSET, so that we have a place to

660        attach the SUBSET.  */

661      superset_entry = ggc_alloc (sizeof (struct alias_set_entry));

662      superset_entry->alias_set = superset;

663      superset_entry->children

664          = splay_tree_new_ggc (splay_tree_compare_ints);

665      superset_entry->has_zero_child = 0;

666      VARRAY_GENERIC_PTR (alias_sets , superset) = superset_entry;

667    }

668 

669    if (subset == 0)

670      superset_entry->has_zero_child = 1;

671    else

672    {

673      subset_entry = get_alias_set_entry (subset);

674      /* If there is an entry for the subset, enter all of its children

675        (if they are not already present) as children of the SUPERSET.  */

676      if (subset_entry)

677      {

678        if (subset_entry->has_zero_child)

679          superset_entry->has_zero_child = 1;

680 

681        splay_tree_foreach (subset_entry->children, insert_subset_children,

682                         superset_entry->children);

683      }

684 

685      /* Enter the SUBSET itself as a child of the SUPERSET.  */

686      splay_tree_insert (superset_entry->children,

687                     (splay_tree_key) subset, 0);

688    }

689  }

 

See that creating superset of value 0 is not allowed, because alias set of 0 must be confined within some alias set to indicate its all-round accessiblity to the confining set. Without this contraint, it is possible to create a tree rooted by the alias set of 0; it definitely will crash the compiler. And note that at line 669, if subset is 0, no real entity would be created, but just remind superset it has child of value 0. And line 678 tells this flag would be propagated up into parent.

The flag has_zero_child above is majorly used in checking alias set conflict taken by below function. It returns 1 if the two specified alias sets may conflict, which means the associated objects may alias to each other.

 

260  int

261  alias_sets_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)               in alias.c

262  {

263    alias_set_entry ase;

264 

265    /* If have no alias set information for one of the operands, we have

266      to assume it can alias anything.  */

267    if (set1 == 0 || set2 == 0

268        /* If the two alias sets are the same, they may alias.  */

269        || set1 == set2)

270      return 1;

271 

272    /* See if the first alias set is a subset of the second.  */

273    ase = get_alias_set_entry (set1);

274    if (ase != 0

275        && (ase->has_zero_child

276            || splay_tree_lookup (ase->children,

277                              (splay_tree_key) set2)))

278      return 1;

279 

280    /* Now do the same, but with the alias sets reversed.  */

281    ase = get_alias_set_entry (set2);

282    if (ase != 0

283        && (ase->has_zero_child

284             || splay_tree_lookup (ase->children,

285                                (splay_tree_key) set1)))

286      return 1;

287 

288    /* The two alias sets are distinct and neither one is the

289      child of the other. Therefore, they cannot alias.  */

290    return 0;

291  }

 

This function should be used carefully. Tree objects behind parameter set1 and set2 must stay at the same type tree (and as result, set1 and set2 if nonzero come from the same tree of alias set). See that may-alias is a conservative predication, two objects if having same member layout (so leads to set1 equates to set2 ) are regarded as may alias.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
for Policy and Practice, 2018, 17(2): 179-195. In this article, Victor Wang Chen Neo examines the implementation of school-based curriculum development (SBCD) in Singapore. SBCD is a process where schools are given greater autonomy to develop and implement their own curriculum, rather than following a standardized national curriculum. The author begins by providing an overview of the history of curriculum development in Singapore, and how the shift towards SBCD came about. He then presents the findings of a study that he conducted, which involved interviews with school leaders who had implemented SBCD in their schools. The author identifies several factors that influenced the successful implementation of SBCD in these schools. These include strong leadership, a clear vision and direction for the school, and a focus on student learning and development. The author also highlights the importance of teacher training and support, as well as collaboration and communication among all stakeholders involved in the curriculum development process. However, the author also notes some challenges that schools face when implementing SBCD. These include a lack of resources, such as time and funding, as well as the need to balance autonomy with accountability to ensure that the curriculum developed meets national standards. Overall, the author suggests that SBCD has the potential to improve the quality of education in Singapore by allowing schools to tailor their curriculum to the needs and interests of their students. However, he also calls for continued support and guidance from the government to ensure that schools are able to implement SBCD effectively.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值