MLIR-AIE 1.4.5.dev
AIECoreMemory.h
Go to the documentation of this file.
1//===- AIECoreMemory.h ------------------------------------------*- C++ -*-===//
2//
3// Copyright (C) 2026 Advanced Micro Devices, Inc.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7//
8// Data memory layout of a core tile. The buffer allocator (AIEAssignBuffers)
9// and the linker script emitter (AIETargetLdScript) both describe the layout
10// with these types, so they compute the same region.
11//
12// AIECoreSymbols.h declares the symbol names that the dialect and the aiecc
13// driver share.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef AIE_DIALECT_AIE_IR_AIECOREMEMORY_H
18#define AIE_DIALECT_AIE_IR_AIECOREMEMORY_H
19
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/Support/MathExtras.h"
23
24#include <algorithm>
25#include <cassert>
26#include <cstdint>
27#include <utility>
28
29namespace xilinx::AIE {
30
31// A half-open [start, start + size) run of bytes. Banks, free runs and a core's
32// data region all use this type.
33struct MemoryRun {
34 int64_t start = 0;
35 int64_t size = 0;
36
37 int64_t end() const { return start + size; }
38 bool contains(int64_t addr) const { return addr >= start && addr < end(); }
39};
40
41// Largest run of free bytes in [0, memSize) whose start is a multiple of
42// `alignBytes`. The occupied half-open intervals may be unsorted and may
43// overlap.
44//
45// AIETargetLdScript grants the core compiler one region for its .data, .rodata
46// and .bss. A core that declares no data_size gets this run as that region.
47//
48// The linker starts .data at a multiple of its strongest section alignment, so
49// an unaligned start loses the difference to padding. A reservation of the
50// exact size then overflows the region.
51inline MemoryRun
53 llvm::SmallVector<std::pair<int64_t, int64_t>> occupied,
54 int64_t alignBytes = 1) {
55 assert(alignBytes > 0 && "alignBytes must be positive");
56 llvm::sort(occupied);
57 MemoryRun best;
58 int64_t cursor = window.start;
59 auto consider = [&](int64_t start, int64_t end) {
60 start = llvm::alignTo(start, alignBytes);
61 if (start < end && end - start > best.size)
62 best = {start, end - start};
63 };
64 for (auto &interval : occupied) {
65 // A zero-length interval occupies no bytes, so it must not split a run.
66 if (interval.first == interval.second)
67 continue;
68 int64_t lo = std::max(interval.first, window.start);
69 int64_t hi = std::min(interval.second, window.end());
70 if (lo >= hi)
71 continue; // falls outside the window
72 consider(cursor, lo);
73 cursor = std::max(cursor, hi);
74 if (cursor >= window.end())
75 return best;
76 }
77 consider(cursor, window.end());
78 return best;
79}
80
81inline MemoryRun
82largestFreeRun(int64_t memSize,
83 llvm::SmallVector<std::pair<int64_t, int64_t>> occupied,
84 int64_t alignBytes = 1) {
85 return largestFreeRunIn({0, memSize}, std::move(occupied), alignBytes);
86}
87
88} // namespace xilinx::AIE
89
90#endif // AIE_DIALECT_AIE_IR_AIECOREMEMORY_H
MemoryRun largestFreeRunIn(MemoryRun window, llvm::SmallVector< std::pair< int64_t, int64_t > > occupied, int64_t alignBytes=1)
MemoryRun largestFreeRun(int64_t memSize, llvm::SmallVector< std::pair< int64_t, int64_t > > occupied, int64_t alignBytes=1)
bool contains(int64_t addr) const
int64_t end() const